如何使用 Bash 和标准实用程序确定两个字符串之间的行数?
How to determine number of lines between two strings using Bash and standard utilities?
我有一个包含如下数据的文件:
abc
abc, Iteration 1
abc
abc, Iteration 2
...
abc
abc, Iteration 19
abc
abc, Iteration 20
我想确定恰好以字符串 "Iteration 1" 和 "Iteration 2" 结束的行之间的行数,并将行数存储到变量 numlines
。在上面的示例中,numlines
应包含值 1。
我想使用 wc -l
、sed
或 awk
。
sed '/Iteration\ 1/,/Iteration\ 2/!d;//d' filename | wc -l
简洁,但总是处理 整个 输入文件 (并且还会创建额外的子进程,因为 wc -l
也必须被调用——尽管这在总体上无关紧要)。
尝试以下 awk
解决方案,一旦找到范围的末尾(它也只创建一个子进程 - 子 shell 被优化以支持简单的 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
的正则表达式在行尾 ($
).
手头的字符串恰好不包含需要转义的正则表达式元字符(使用 \
),但在其他情况下您可能必须这样做。
如果要匹配的字符串不是事先已知的文字,则通用转义将很困难;在这种情况下,考虑 ,它基于 strings,而不是正则表达式。
目前所有的解决方案都使用正则表达式,而不是字符串,因此当您的字符串包含 RE 元字符时将会失败。这是如何按照您在问题中要求的那样使用字符串执行您想要的操作:
$ awk '
BEGIN {
begStr = "Iteration 1"
endStr = "Iteration 2"
}
index([=10=],begStr) == 1 + length([=10=]) - length(begStr) { begNr = NR }
index([=10=],endStr) == 1 + length([=10=]) - length(endStr) { print NR - begNr - 1 }
' file
1
我有一个包含如下数据的文件:
abc
abc, Iteration 1
abc
abc, Iteration 2
...
abc
abc, Iteration 19
abc
abc, Iteration 20
我想确定恰好以字符串 "Iteration 1" 和 "Iteration 2" 结束的行之间的行数,并将行数存储到变量 numlines
。在上面的示例中,numlines
应包含值 1。
我想使用 wc -l
、sed
或 awk
。
sed '/Iteration\ 1/,/Iteration\ 2/!d;//d' filename | wc -l
wc -l
也必须被调用——尽管这在总体上无关紧要)。
尝试以下 awk
解决方案,一旦找到范围的末尾(它也只创建一个子进程 - 子 shell 被优化以支持简单的 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
的正则表达式在行尾 ($
).
手头的字符串恰好不包含需要转义的正则表达式元字符(使用 \
),但在其他情况下您可能必须这样做。
如果要匹配的字符串不是事先已知的文字,则通用转义将很困难;在这种情况下,考虑
目前所有的解决方案都使用正则表达式,而不是字符串,因此当您的字符串包含 RE 元字符时将会失败。这是如何按照您在问题中要求的那样使用字符串执行您想要的操作:
$ awk '
BEGIN {
begStr = "Iteration 1"
endStr = "Iteration 2"
}
index([=10=],begStr) == 1 + length([=10=]) - length(begStr) { begNr = NR }
index([=10=],endStr) == 1 + length([=10=]) - length(endStr) { print NR - begNr - 1 }
' file
1