【问题标题】:reading lines in a text file with special characters specifically as quoted '<', '>' in bash shell读取文本文件中带有特殊字符的行,特别是在 bash shell 中引用的“<”、“>”
【发布时间】:2021-01-11 22:15:31
【问题描述】:

我有一个文本文件,它是两个 grepped 文件的输出差异。文本文件有如下行 我需要读取文件(循环遍历文本文件中的行)并根据“”右侧的文本做一些事情.

编辑添加细节:

  1. 的右轴
  2. 如果其中任何一个,我需要将内容存储到一个变量中,并获取第一个(ABCDEF)第三个(10)并在其他两个文件之一中搜索(将 grep)它们,如果找到则打印一条消息并在电子邮件 DL 中附加这些文件名。所有文件名和目录都存储在单独的变量中。

我该怎么做。

ps:对文本格式和 bash/shell 命令有基本的了解,但仍在学习脚本语法。谢谢。

ABCDEF,20200101,10                   <
PQRSTU,20200106,11                   <
LMNOPQ,20200101,12                   <
EFGHIJ,20200102,13                   <
KLMNOP,20200103,14                   <
STUVWX,20200104,15                   <
PQRSTU,20200105,16                   <
                                     > LMNOPQ,20200101,10
ABCDEF,20200107,17                   <

我现在做错了什么?

while IFS= read -r line; do
if $line =~ ([^[:blank:]]+)[[:blank:]]+\< 
    then
    IFS=, read -r f1 f2 f3 <<< "${BASH_REMATCH[1]}"
        #echo "f1=$f1 f2=$f2 f3=$f3"
zgrep "$f1" file1 | grep "with seq $f3" || zgrep "$f1" file2 | grep "with seq $f3"
elif $line =~ \>[[:blank:]]+([^[:blank:]]+)
    then
    IFS=, read -r g1 g2 g3 <<< "${BASH_REMATCH[1]}"
        #echo "g1=$g1 g2=$g2 g3=$g3"
zgrep "$g1" file3 | grep "with seq $g3" || zgrep "$g1" file3 | grep "with seq $g3"        
fi

【问题讨论】:

标签: bash shell if-statement scripting special-characters


【解决方案1】:

请您尝试以下方法:

#!/bin/bash

while IFS= read -r line; do
    if [[ $line =~ ([^[:blank:]]+)[[:blank:]]+\< || $line =~ \>[[:blank:]]+([^[:blank:]]+) ]]; then
        IFS=, read -r f1 f2 f3 <<< "${BASH_REMATCH[1]}"
        echo "f1=$f1 f2=$f2 f3=$f3"
        # do something here with "$f1", "$f2" and "$f3"
    fi
done < file.txt

输出:

f1=ABCDEF f2=20200101 f3=10
f1=PQRSTU f2=20200106 f3=11
f1=LMNOPQ f2=20200101 f3=12
f1=EFGHIJ f2=20200102 f3=13
f1=KLMNOP f2=20200103 f3=14
f1=STUVWX f2=20200104 f3=15
f1=PQRSTU f2=20200105 f3=16
f1=LMNOPQ f2=20200101 f3=10
f1=ABCDEF f2=20200107 f3=17

请将echo "f1=$f1 f2=$f2 f3=$f3" 行修改为您想要的 命令如grep

  • 正则表达式([^[:blank:]]+)[[:blank:]]+\&lt; 匹配包含&lt; 的行 并将 bash 变量 ${BASH_REMATCH[1]} 分配给 LHS。 另一方面,正则表达式 \&gt;[[:blank:]]+([^[:blank:]]+) 对 包含&gt; 的行。
  • IFS=, read -r f1 f2 f3 &lt;&lt;&lt; "${BASH_REMATCH[1]}" 语句拆分 bash 变量 在 , 上,并将 f1、f2 和 f3 分配给字段。

请注意,如果输入文件非常大,bash 解决方案可能不会 在执行时间上保持高效。我使用 bash 只是因为它很方便 将变量传递给您的 grep 命令。

编辑

关于您问题中的更新脚本,请参考以下修改:

while IFS= read -r line; do
    if [[ $line =~ ([^[:blank:]]+)[[:blank:]]+\< ]]; then
        IFS=, read -r f1 f2 f3 <<< "${BASH_REMATCH[1]}"
        # echo "f1=$f1 f2=$f2 f3=$f3"
        result=$(zgrep "$f1" file1 | grep "with seq $f3" || zgrep "$f1" file2 | grep "with seq $f3")
    elif [[ $line =~ \>[[:blank:]]+([^[:blank:]]+) ]]; then
        IFS=, read -r g1 g2 g3 <<< "${BASH_REMATCH[1]}"
        # echo "g1=$g1 g2=$g2 g3=$g3"
        result=$(zgrep "$g1" file3 | grep "with seq $g3" || zgrep "$g1" file3 | grep "with seq $g3")
    fi
    if [[ -n $result ]]; then
        echo "result = $result"
    fi
done < file.txt

【讨论】:

  • 感谢@tshiono 绝对有帮助,向您学习了正则表达式的用法。一定会奖励你的。将通过我的解决方案并返回。只是在我的情况下,需要在单独的“如果条件”中处理两个正则表达式(您建议的)。让我解决我的溶胶。再次感谢。
  • 感谢您的及时反馈。很高兴知道它有效。如果您有任何问题或其他要求,请随时问我。 BR。
  • 添加了我的进一步评论...@tshiono
  • 根据我在任一文件中的 zgrep 输出,我应该能够打印一些内容并发送带有文件附件的电子邮件通知。
  • 1) 您需要用[[]] 括起来正则表达式测试。 2) 缺少done 语句,它与第一行中的do 相对应。请查看我更新的答案,其中包括这些更正。至于邮寄功能,可以参考this one等一些网站自己解决。
猜你喜欢
  • 2018-02-05
  • 2011-08-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多