我可以使用哪些 unix 命令来确定单词在文本中出现的行跨度?“跨度”等于单词的最后一个实例的行号减去单词的第一个实例的行号。
1| unix is on two lines
2| once above, and once below
3| unix
在上面的例子中,“unix”的“跨度”将是 2(3-1)。
到目前为止,我一直在尝试使用 grep -n,但我认为 grep 功能不够强大。也许可以使用 sed 或 awk?
谢谢!
答案1
使用awk
命令
awk '{ if($0 ~ /PATTERN/) { if(!FIRST) FIRST=NR; LAST=NR } } END { print LAST-FIRST }' FILE
怎么运行的
awk '{ COMMANDS } END { FINALCOMMAND }' FILE
COMMMANDS
对 的每一行执行FILE
。随后,它执行
FINALCOMMAND
。if($0 ~ /PATTERN/) { ... }
检查PATTERN
行 ($0
) 中是否出现。如果有,
...
则执行。The first time the pattern occurs,
FIRST` 将为空。因此,
if(!FIRST) FIRST=NR
将行号(NR
)存储在中FIRST
。对于每次出现,
LAST=NR
将把行号 (NR
) 存储在 中LAST
。处理完所有出现的情况后,
LAST
将保存最后一次出现的行号。print LAST-FIRST
打印最后一行和第一行号之间的差异。
仅使用grep
,head
并且tail
脚本
MATCHES=$(grep -n PATTERN FILE)
FIRST=$(echo "$MATCHES" | head -n 1 | grep -Po "^\d+"); [ $FIRST ] || FIRST=0
LAST=$(echo "$MATCHES" | tail -n 1 | grep -Po "^\d+"); [ $LAST ] || LAST=0
SPAN=$(($LAST - $FIRST))
怎么运行的
grep -n PATTERN FILE
显示FILE
匹配的所有行PATTERN
,并在其前面加上行号。echo "$MATCHES" | head -n 1
显示第一的行MATCHES
,并grep -Po "^ *\d+"
过滤掉除行号之外的所有内容。之后,
[ $FIRST ] || FIRST=0
检查是否FIRST
已定义。如果尚未定义,则将其设置为0
。echo "$MATCHES" | tail -n 1
显示最后的行MATCHES
,并grep -Po "^ *\d+"
过滤掉除行号之外的所有内容。之后,
[ $LAST ] || LAST=0
检查是否LAST
已定义。如果尚未定义,则将其设置为0
。$(($LAST - $FIRST))
计算最后一行和第一行号之间的差值。
答案2
这将找到第一的和最后的单词的出现(即不考虑中间单词)...
注意:sed
命令i
和a
(插入和附加)必须是一行中的最后一个命令。
eval "$(sed -ne "1 i b=
/\<$word\>/{=; i ;e=
=}
$ {a ;echo \$((e-b))
}
" "$file" | tr -d '\n')"
或者这个,管道sed到sed,但也许更简单。
eval "$(sed -n "/\<$word\>/=" "$file" |
sed -n '1{i b=
p};${i;e=
p; a;echo \$((e-b))
}' | tr -d '\n')"
答案3
这可能对你有用:
sed '/unix/=;d' file | sed '1h;$!d;G;s/\n/-/' | bc