【问题标题】:Parsing a file in backward and forward direction向后和向前解析文件
【发布时间】:2017-08-25 14:02:28
【问题描述】:

我有一个很长的周期性结构文件(三个点类似于行数不一定相等,n 只是一个索引):

...
string bar text1 (n-2)
...
string bar text1 (n-1)
...
string bar text1 (n)
...
STRING FOO
elements1
elements1
...
string bar text2 (n-2)
...
string bar text2 (n-1)
...
string bar text2 (n)
...
STRING FOO
elements2
elements2
...

我正在尝试制作一个 bash 脚本来解析这个文件,并将以下信息打印到另一个文件:找到 STRING FOO 的所有外观并打印到新文件 elements(可以是两个,对于例如)加上string bar n。为了实现这一点,我尝试了以下命令:

grep -A 2 "STRING FOO"  input_file.txt   >> output_file.txt
grep -B 200 "STRING FOO" input_file.txt | tac | sed -n '/'string bar n'/ { p ; q }' >> output_file.txt

预期输出:

STRING FOO
elements1
elements1
string bar text1
STRING FOO
elements2
elements2
string bar text2

数字 200 只是我需要返回多少行的“猜测”。这些命令除了效率低下之外,还不能正常工作。我真的很感激别人的帮助。

【问题讨论】:

    标签: bash parsing sed grep


    【解决方案1】:

    您可以在一个 gung-ho Awk 命令中使用这一切,为此,

    awk '/string bar/{ pat=$0; }/\<STRING FOO\>/{c=NR+2}(NR<=c){print}(NR==c){print pat}' file
    

    根据需要仅输出以下行,

    STRING FOO
    elements1
    elements1
    string bar text1 (n)
    STRING FOO
    elements2
    elements2
    string bar text2 (n)
    

    【讨论】:

    • 从 OP 的用法来看,string bar n 似乎不是整行,而是附加在从STRING FOO 开始的三行之后
    • 类似awk '/string bar n/{s=$0} /STRING FOO/{print $0; f=1; c=2; next} f &amp;&amp; c--; f &amp;&amp; c==0{print s; f=0}' file
    • @Sundeep:感谢尝试,将其保留为符合他实际要求的 OP
    • @Sundeep:但我建议在您的示例中使用整个字符串匹配,就像在我的回答中一样:)
    • 我的看法是,如果该字符串是恒定的,OP 就不必费心 grep+tac+sed 的第二个命令
    【解决方案2】:
    $ sed -n '/string bar/h;/STRING FOO/{N;N;x;H;g;p}' in.txt
    

    输出:

    STRING FOO
    elements1
    elements1
    string bar text1 (n)
    STRING FOO
    elements2
    elements2
    string bar text2 (n)
    
    1. sed flag-n表示“默认不打印输出。打印可以通过命令p来完成。
    2. /string bar/h - 当找到字符串“string bar”时,将其保存(命令h)在保存缓冲区中。
    3. /STRING FOO/{ .. } - 找到字符串“STRING FOO”时,在括号内执行命令。
    4. N;N - 将下一行(命令 N)两行附加到当前行(即“STRING FOO”+ 两行“元素”)。
    5. x - 交换保持和模式缓冲区。现在在保持缓冲区中,3 行带有“STRING FOO”,两行带有“elements”。 并在当前模式缓冲区“字符串栏”中。
    6. H - 追加当前行以保存缓冲区。
    7. g - 从保持缓冲区获取字符串到当前模式空间。
    8. p - 从当前模式空间打印行。

    【讨论】:

    • 感谢您的回答!它只能工作一次,并且文件的结构会定期重复一定次数,我想要所有这些。
    • @Panadestein 您可以通过修改输入以包含至少两个这样的结构来明确地向问题添加预期输出来明确这一点......
    • @Sundeep,你完全正确,但不清楚。我希望现在是。
    • @Panadestein,我修复答案
    • 非常感谢您的详细回答@komar 它也有效!
    【解决方案3】:

    与:

    grep "STRING FOO\|string bar" file.out | grep -B 1 STRING FOO | head -n 1 
    

    您将拥有您的"string bar text1 (n)"

    并为您的“元素”重复相同的逻辑。

    真诚的。

    【讨论】:

      猜你喜欢
      • 2010-11-19
      • 1970-01-01
      • 2016-04-10
      • 1970-01-01
      • 1970-01-01
      • 2019-03-05
      • 1970-01-01
      • 2016-01-30
      • 1970-01-01
      相关资源
      最近更新 更多