在同一文件中最后一个匹配的String2之后,返回与文件中的String1匹配的所有行

时间:2014-01-30 19:21:26

标签: linux bash sed grep sh

我想出了如何获取文件中最后一个匹配单词的行号:

cat -n textfile.txt | grep " b " | tail -1 |  cut -f 1

它给了我1787的值。因此,我手动将其传递给sed命令,以搜索包含该行号后面的“刀片已关闭”的行,并且它成功返回所有行

sed -n '1787,$s/blades are down/&/p' myfile.txt

有没有办法可以通过变量或文件将第一个命令的行号传递给第二个命令,所以我可以在脚本中自动执行它们?

谢谢。

4 个答案:

答案 0 :(得分:1)

您可以使用:

  • 命令替换以捕获变量中第一个命令的结果。
  • 使用sed命令
  • 中的变量的简单字符串连接
startLine=$(grep -n ' b ' textfile.txt | tail -1 | cut -d ':' -f1)

sed -n ${startLine}',$s/blades are down/&/p' myfile.txt

您并不严格需要中间变量 - 您只需使用:

sed $(grep -n ' b ' textfile.txt | tail -1 | cut -d ':' -f1)',$s/blades are down/&/p' myfile.txt`

但是首先对命令替换的结果进行错误检查可能是有意义的。

请注意,我使用grep的{​​{1}}选项简化了第一个命令,该选项在每次匹配前将行号与-n分开。

答案 1 :(得分:1)

您可以通过将两个命令与xargs连接来实现。 'xargs -I%'允许您从上一个命令中获取stdin,并在下一个命令中随时放置它。 '%'是您写'1787'的地方:

cat -n textfile.txt | grep " b " | tail -1 |  cut -f 1 |  xargs -I % sed -n %',$s/blades are down/&/p' myfile.txt

答案 2 :(得分:0)

首先我们可以在string2的最后一次匹配后得到文件的“一半”,然后你可以使用grep来匹配所有的string1

tac your_file | awk '{ if (match($0, "string2")) { exit ; } else {print;} }' | \
  grep "string1"

但如果您不关心订单,订单会被撤销。但是,如果你关心,只需在管道tac的末尾添加另一个|

答案 3 :(得分:0)

这可能适合你(GNU sed):

sed -n '/\n/ba;/ b /h;//!H;$!d;x;//!d;s/$/\n/;:a;/\`.*blades are down.*$/MP;D' file

这将读取存储空间中第一个字符串(" b ")的最后一个匹配项后面的所有行的文件。

在文件末尾,它交换到保留空间,检查它确实至少有一个匹配,然后打印出与第二个字符串匹配的行("blades are down")。

N.B。它通过在保留空间的末尾添加一个新行来实现结束案例(/\n/),最终将被抛弃。这也适用于最后一行边缘条件。