如何获取 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-DATAbegincounting 标志就会导致 lines 递增。这意味着 - 包含 START-OF-DATA 的行也被计算在内

希望这对以后的人有所帮助。

又一个技巧:

$ n=$(( $(sed -n '/START-OF-DATA/,/END-OF-DATA/p' file | wc -l) - 2 ))
$ echo $n
4