计算模式匹配之前/之后的总行数

计算模式匹配之前/之后的总行数

我有一长串 IP 地址,但没有按顺序排列。我需要查找特定 IP 地址之前/之后有多少个 IP 地址。我怎样才能实现这个目标?

答案1

匹配之前和之后的行数,包括匹配(即,如果要排除匹配,则需要从结果中减去 1):

sed -n '0,/pattern/p' file | wc -l
sed -n '/pattern/,$p' file | wc -l

但这与 IP 地址无关。

答案2

也许最简单的是,

sed -n '/pattern/{=; q;}' file

感谢@JoshepR指出错误

答案3

我用两种方式做到了这一点,但我认为我最喜欢这个:

: $(( afterl=( lastl=$(wc -l <~/file) ) - 2 -
  $(( beforel=( matchl=$(sed -n "/$IP/{=;q;}" <~/file) ) - 1
)) ))
for n in last match afters befores
do  printf '%s line%s :\t%d\n' \
        "${n%s}" "${n##*[!s]}" $((${n%s}l))
done

这会将所有这些保存为当前 shell 变量 - 并随后在 for 循环中评估它们以进行输出。它计算文件中的总行数wc,并获取第一个匹配的行号sed

其输出:

last line :     1000
match line :    200
after lines :   799
before lines :  199

我也做了:

sed -n "/$IP/=;\$=" ~/file |  
tr \\n \  | { 
IFS=' ' read ml ll 
printf '%s line%s:\t%d\n' \
    last '' $((ll=${ll##* }))
    match '' $ml \
    after s "$((al=ll-ml-1)) \ 
    before s $((bl=ml-1))
}

sed仅打印匹配的行号和最后的行号,然后tr将中间的\newlines 转换为,并将read第一个sed结果读入$ml,将所有其他结果读入$ll$ll稍后再次设置时,可以通过从 的扩展中剥离除最后一个结果之外的所有结果来处理可能的多个匹配情况。

其输出:

last line :     1000
match line :    200
after lines :   799
before lines :  199

两种方法都在按以下方式生成的文件上进行了测试:

IP='some string for which I seek' 
for count in 1 2 3 4 5 
do  printf '%.199d%s\n' 0 "$IP" 
done | tr 0 \\n >~/file 

确实如此,按行号:

  1. 设置搜索字符串
  2. 循环五次以确保有多个匹配项
  3. 打印 199 个零,然后"$IP"打印\newline
  4. 管道输出到tr- 将零转换为\newlines 然后转换为~/file

答案4

awk报告最后一场比赛之前和之后的行数的解决方案

awk '/192\.168\.1\.1/{x=NR};{y=NR} END{printf "before-%d, after-%d\n" , x-1, y-x}'  file

相关内容