Bash,两行之间使用指定字符串进行grep

use*_*968 54 regex bash grep

例:

a43
test1
abc
cvb
bnm
test2
kfo
Run Code Online (Sandbox Code Playgroud)

我需要test1和test2之间的所有行.在这种情况下,正常的grep不起作用.你有什么建议吗?

Jot*_*tne 51

她是一些test1 这些将打印test2test1

awk '/test1/{f=1} /test2/{f=0;print} f'
awk '/test1/{f=1} f; /test2/{f=0}' 
awk '/test1/,/test2/'
Run Code Online (Sandbox Code Playgroud)

test1
abc
cvb
bnm
test2
Run Code Online (Sandbox Code Playgroud)

这些版画之间的数据test2test1

awk '/test1/{f=1;next} /test2/{f=0} f' 
awk '/test2/{f=0} f; /test1/{f=1}' 
Run Code Online (Sandbox Code Playgroud)

abc
cvb
bnm
Run Code Online (Sandbox Code Playgroud)


dev*_*ull 45

你可以使用sed:

sed -n '/test1/,/test2/p' filename
Run Code Online (Sandbox Code Playgroud)

为了排除包含test1和的行test2,比如说:

sed -n '/test1/,/test2/{/test1/b;/test2/b;p}' filename
Run Code Online (Sandbox Code Playgroud)

  • 要排除这些行,可以缩短为`sed -n'/ test1 /,/ test2/{// b; p}'` (4认同)
  • 或者,如果您在sed字符串中使用shell扩展,那么可以执行`start ="test1"; 结束= "test2的"; sed -n"/ $ start /,/ $ end/{/ $ start/b;/$ end/b; p}"filename`.这样你只需要输入一次搜索模式. (3认同)

phi*_*hem 10

如果你只能使用grep:

grep -A100000 test1 file.txt | grep -B100000 test2 > new.txt
Run Code Online (Sandbox Code Playgroud)

grep -A然后一个数字获取匹配字符串后面的行,并grep -B获取匹配字符串之前的行.在这种情况下,数字100000必须足够大,以包括前后的所有行.

如果你不想包含test1和test2,那么之后可以删除它们grep -v,它会打印除匹配行之外的所有内容:

egrep -v "test1|test2" new.txt > newer.txt
Run Code Online (Sandbox Code Playgroud)

或者一行中的所有内容:

grep -A100000 test1 file.txt | grep -B100000 test2 | egrep -v "test1|test2" > new.txt 
Run Code Online (Sandbox Code Playgroud)

  • 只是想指出显而易见的是,如果test1/test2对在输入中出现多次,则可能会失败. (3认同)

Avi*_*Raj 6

是的,正常的grep不会这样做.但grep with -Pparameter将完成这项工作.

$ grep -ozP '(?s)test1\n\K.*?(?=\ntest2)' file
abc
cvb
bnm
Run Code Online (Sandbox Code Playgroud)

\K丢弃先前匹配的字符,在最后打印时,正向前导(?=\ntest2)断言匹配必须后跟\n换行字符,然后是test2字符串.

  • 这是哪种 grep 口味?我在 mac os 上,没有 -P。-P 在上面的 grep 上下文中有什么含义?如果它们是解决方案的一部分,那么解释 -oz 也将有所帮助。在 mac os 中,grep -o 是 --only-matching 而 -z 是 --decompress。前者可能是相关的,但后者似乎并不相关。 (2认同)