我有一个包含以下数据的文件:
application/octet-stream
我想确定行之间的行数,它们在字符串“Iteration 1”和“Iteration 2”中完全结束,并将行数存储到变量abc
abc, Iteration 1
abc
abc, Iteration 2
...
abc
abc, Iteration 19
abc
abc, Iteration 20
。在上面的示例中,numlines
应包含值1。
我想使用numlines
,wc -l
或sed
。
答案 0 :(得分:4)
Vijay's helpful sed
answer简洁,但总是处理整个输入文件(并且还会创建额外的子进程,因为必须调用wc -l
好吧 - 尽管总的来说这并不重要。)
尝试以下 awk
解决方案,在找到范围结束时立即退出(它也只创建一个子进程 - subshell被优化而不是简单的awk
命令);对于大输入文件,这可能很重要,具体取决于文件在文件内的位置:
numlines=$(awk '/Iteration 1$/ {b=NR; next} /Iteration 2$/ {print NR-b-1; exit}' file)
向karakfa提供帮助优化命令的提示。
注意:/Iteration 1$/
和/Iteration 2$/
是正则表达式,它们在一行的末尾匹配字符串Iteration 1
和Iteration 2
( $
)。
手头的字符串不包含需要转义的正则表达式元字符(使用\
),但在其他情况下可能必须这样做。
如果要匹配的字符串不是事先已知的文字,则通用转义将很困难;在这种情况下,请考虑Ed Morton's solution,它基于字符串,而不是正则表达式。
功能
答案 1 :(得分:3)
sed '/Iteration\ 1/,/Iteration\ 2/!d;//d' filename | wc -l
答案 2 :(得分:1)
到目前为止,所有解决方案都使用regexp而不是字符串,因此当字符串包含RE元字符时会失败。这就是如你在问题中所要求的那样用字符串做的事情:
$ awk '
BEGIN {
begStr = "Iteration 1"
endStr = "Iteration 2"
}
index($0,begStr) == 1 + length($0) - length(begStr) { begNr = NR }
index($0,endStr) == 1 + length($0) - length(endStr) { print NR - begNr - 1 }
' file
1