2013-04-25 112 views
1

我想在另一个字符串之前找到前面的字符串。例如:Bash:在文件的另一个字符串之前找到一个字符串

StringA <stuff 1> 
StringA <stuff 2> 
StringD 
... 
StringB <stuff 3> 
StringA <stuff 4> 
StringA <stuff 5> 
StringA <stuff 6> 
StringD 
StringB <stuff 7> 

我想查找所有在文件中的StringB前面的“StringA”。

此示例中的输出是:

StringA <stuff 2> 
StringA <stuff 6> 

我能够做到通过使用发现所有的StringB的行号:grep的-n“StringB”

那么我可以用SED -n 1,$ line_numberp这使我从第1行转到StringB行。我做grep“StringA”|尾-n1

这似乎是工作,但有点麻烦。有没有更好的方法来达到预期的效果?

+0

4和5呢?就我所知,这些先于B。 – squiguy 2013-04-25 00:35:18

+0

我只是寻找前一个,唯一的最后一个在stringB之前。 – user1777907 2013-04-25 01:15:21

回答

1

使用awk:

awk '/^StringB/ { if(lastline ~ /^StringA/) {print lastline }} {lastline=$0}' $file 

StringA和StringB可以正则表达式。

+0

非常感谢! – user1777907 2013-04-25 01:19:25

+0

有一个问题,如果文件的最后一行是StringA(并且它后面没有StringB),它似乎打印最后一个StringA。谢谢。 – user1777907 2013-04-25 01:22:25

1
sed '/String[AB]/!d' input | 
    sed -n -e '/StringA/{:l /StringA/h;n;/StringB/{x;p;b};bl}' 

搭配点评:

sed '/String[AB]/!d' input |  # remove lines not containing StringA/B 
    sed -n -e '/StringA/{   # if line contains StringA, then 
     :l       # loop until StringB 
      /StringA/h;    # keep the most recent A in the hold space 
      n;      # read a newline (overwrite pattern space) 
      /StringB/!bl;   # loop up... 
      x;p;b     # get the most recent A, and print 
    }' 
+0

我希望我写了那个sed脚本! – user1666959 2013-04-25 02:59:15

3
grep "\(StringA\|StringB\)" $file_name | grep -B 1 StringB | grep StringA 
+0

非常感谢! – user1777907 2013-04-25 01:14:24

+1

@perreal我想过,但没有使用它,因为它不太可能op是询问实际字符串匹配'String [AB]' – Alex 2013-04-25 02:21:07

0

这可能为你工作(GNU SED):

sed ':a;$!N;/^StringA/!D;/^\(StringA\).*\n\1/D;/.*StringB/!ba;P;D' file 

这消除了重复StringA线保留了最后,并遇到StringB行打印出模式空间的第一个字符串时。

相关问题