如何获取 Linux 中两个单词之间的行数
How to get row count between two words in Linux
下面是我的源文件的模式:
Col1
Col2
col3
colN
START-OF-DATA
val1|val2|val3|valN
val1|val2|val3|valN
val1|val2|val3|valN
val1|val2|val3|valN
END-OF-DATA
TIMEFINISHED=Mon Apr 21 20:28:55 EDT 2014
END-OF-FILE
我想找出 START-OF-DATA 和 END-OF-DATA 之间的行数。最初我不得不为一个文件做这件事所以我只使用
V_ROWCOUNT=`wc -l ${V_LOC}/${V_FILENM} | awk -F" " '{print (-1)}'`
然后减去非数据行的静态行数。现在我要做的是概括,输入文件中唯一常见的是 START-OF-DATA 和 END-OF-DATA。所以我想找到这些拖车标签之间的行数。
能否告诉我如何实现?
谢谢
echo "$(grep -n 'END-OF-DATA' data | cut -d: -f1)-$(grep -n 'START-OF-DATA' data | cut -d: -f1)" | bc
这是做什么的:
grep
for END-OF-DATA
,包括行号
- 输出
10:END-OF-DATA
cut
输出,由 :
分隔,获取字段 1
- 输出
10
- 重复
START-OF-DATA
- 使用
echo
将其构建到 10-5
- 将其输入
bc
(基本计算器)进行评估
下面是使用 awk 的方法:
rowcount=$(awk '/END-OF-DATA/{print NR-start; exit} /START-OF-DATA/{start=NR+1}' "$v_loc/$v_filenm")
这里也是一样的,但是使用 START-OF-DATA 和 END-OF-DATA 作为变量,而不是将它们硬编码到 awk 脚本中:
start=START-OF-DATA end=END-OF-DATA
rowcount=$(awk -v start="$start" -v end="$end" '[=11=] ~ end { print NR - s; exit } [=11=] ~ start { s = NR + 1 }' "$v_loc/$v_filenm")
附带说明一下,您应该避免将大写变量用于内部目的,因为您可能会覆盖特殊的 shell 变量和环境变量。
在将变量扩展用作参数时始终引用它们也是一个好主意,以避免在结果中发生不必要的分词和路径名扩展。
这条语句做到了:
set -- $(egrep -n 'START-OF-DATA|END-OF-DATA' | cut -d ':' -f1 ); expr -
只是一个替代和更具描述性的 awk
示例如下:
awk '
BEGIN {
begincounting = 0;
stopcounting = 0;
lines = 0;
}
{
if (=="START-OF-DATA") { begincounting = 1; }
if (=="END-OF-DATA") { stopcounting = 1; }
if (begincounting==1 && stopcounting==0) { lines++; }
}
END {
print "Total lines: "lines-1
}' test.txt
说明
BEGIN { ... }
是我们放置一些变量或标志的地方。
- 接下来是正文。
- 如果我们注意到第一列是 START-OF-DATA
,我们将标志 begincounting
设置为 1
- 如果我们注意到第一列是 END-OF-DATA
,我们将标志 stopcounting
设置为 1
- 每当我们注意到
begincounting
已设置但 stopcounting
未设置时,我们增加 lines
变量
- 读取信息结束,我们打印出行数减1
- 为什么是负 1?请记住,一旦找到
START-OF-DATA
,begincounting
标志就会导致 lines
递增。这意味着 - 包含 START-OF-DATA 的行也被计算在内
希望这对以后的人有所帮助。
又一个技巧:
$ n=$(( $(sed -n '/START-OF-DATA/,/END-OF-DATA/p' file | wc -l) - 2 ))
$ echo $n
4
下面是我的源文件的模式:
Col1
Col2
col3
colN
START-OF-DATA
val1|val2|val3|valN
val1|val2|val3|valN
val1|val2|val3|valN
val1|val2|val3|valN
END-OF-DATA
TIMEFINISHED=Mon Apr 21 20:28:55 EDT 2014
END-OF-FILE
我想找出 START-OF-DATA 和 END-OF-DATA 之间的行数。最初我不得不为一个文件做这件事所以我只使用
V_ROWCOUNT=`wc -l ${V_LOC}/${V_FILENM} | awk -F" " '{print (-1)}'`
然后减去非数据行的静态行数。现在我要做的是概括,输入文件中唯一常见的是 START-OF-DATA 和 END-OF-DATA。所以我想找到这些拖车标签之间的行数。
能否告诉我如何实现?
谢谢
echo "$(grep -n 'END-OF-DATA' data | cut -d: -f1)-$(grep -n 'START-OF-DATA' data | cut -d: -f1)" | bc
这是做什么的:
grep
forEND-OF-DATA
,包括行号- 输出
10:END-OF-DATA
- 输出
cut
输出,由:
分隔,获取字段1
- 输出
10
- 输出
- 重复
START-OF-DATA
- 使用
echo
将其构建到 - 将其输入
bc
(基本计算器)进行评估
10-5
下面是使用 awk 的方法:
rowcount=$(awk '/END-OF-DATA/{print NR-start; exit} /START-OF-DATA/{start=NR+1}' "$v_loc/$v_filenm")
这里也是一样的,但是使用 START-OF-DATA 和 END-OF-DATA 作为变量,而不是将它们硬编码到 awk 脚本中:
start=START-OF-DATA end=END-OF-DATA
rowcount=$(awk -v start="$start" -v end="$end" '[=11=] ~ end { print NR - s; exit } [=11=] ~ start { s = NR + 1 }' "$v_loc/$v_filenm")
附带说明一下,您应该避免将大写变量用于内部目的,因为您可能会覆盖特殊的 shell 变量和环境变量。
在将变量扩展用作参数时始终引用它们也是一个好主意,以避免在结果中发生不必要的分词和路径名扩展。
这条语句做到了:
set -- $(egrep -n 'START-OF-DATA|END-OF-DATA' | cut -d ':' -f1 ); expr -
只是一个替代和更具描述性的 awk
示例如下:
awk '
BEGIN {
begincounting = 0;
stopcounting = 0;
lines = 0;
}
{
if (=="START-OF-DATA") { begincounting = 1; }
if (=="END-OF-DATA") { stopcounting = 1; }
if (begincounting==1 && stopcounting==0) { lines++; }
}
END {
print "Total lines: "lines-1
}' test.txt
说明
BEGIN { ... }
是我们放置一些变量或标志的地方。- 接下来是正文。
- 如果我们注意到第一列是 START-OF-DATA ,我们将标志
- 如果我们注意到第一列是 END-OF-DATA ,我们将标志
- 每当我们注意到
begincounting
已设置但stopcounting
未设置时,我们增加lines
变量 - 读取信息结束,我们打印出行数减1
- 为什么是负 1?请记住,一旦找到
START-OF-DATA
,begincounting
标志就会导致lines
递增。这意味着 - 包含 START-OF-DATA 的行也被计算在内
begincounting
设置为 1
stopcounting
设置为 1
希望这对以后的人有所帮助。
又一个技巧:
$ n=$(( $(sed -n '/START-OF-DATA/,/END-OF-DATA/p' file | wc -l) - 2 ))
$ echo $n
4