假设我有:
content line 1
content line 2
blabla *my_pattern_str* (1st occurrence)
...
content line x
blabla *my_pattern_str* (nth occurrence <- I want to print from the beginning line up to here)
content line y
content line y+1
...
我想在 my_pattern_str 的第n次出现之前打印所有行。如何使用sed
(或grep
或awk
等类似命令)执行此操作?
答案 0 :(得分:3)
你可以用它。变量N
是最大次数。它将处理文件的其余部分,但我不认为这是一个大问题:
awk -vN=2 'n<N;/my_pattern/{++n}' file
每次匹配模式时递增计数器。只要计数器低于变量N
,就打印该行。
答案 1 :(得分:2)
根据需要调整7
和my_pattern
。
awk -v N=7 '{print}/my_pattern/&&--N<=0{exit}'
更隐晦地,以下内容也有效:
awk -v N=7 '1;/my_pattern/&&--N<=0{exit}'
上述两个实际上都停留在包含模式的第N行,而不是模式的第N次出现。如果您想要第N次出现模式:
awk -v N=7 -v M=my_pattern '1;(N-=gsub(M,""))<=0{exit}'
例如:
printf %s\\n line1 "pattern in line 2" "pattern pattern in line 3" line4 pattern |
awk -v N=3 -v M=pattern '1;(N-=gsub(M,""))<=0{exit}'
=&GT;
line1
pattern in line 2
pattern pattern in line 3
答案 2 :(得分:1)
这太可怕了,但它完全符合你的要求。
cat input_file.txt \
| tr '\n' '\0' \
| sed -e 's:my_pattern:my_pattern\
:g' \
| head -n$X \
| tr -d '\n' \
| tr '\0' '\n'
请注意在sed模式中使用转义的换行符很棒 - 我不确定是否可以避免这种情况。
这里的想法是:
\0
head -n X
抓取第一个X
个匹配\0
个字符答案 3 :(得分:0)
如果图案确实存在,那么只打印那些线条,如果找不到,则不打印所有内容:
awk '{lines[NR]=$0}/pattern/{for(i=1;i<=NR;++i)print lines[i];exit}' file