unix Grep一个数字大于45的字符串

vnjpjtjt  于 2023-08-04  发布在  Unix
关注(0)|答案(3)|浏览(183)

我在一个目录中有多个文件。我想提取所有文件中包含的每一行,其中整数值大于45。
目前,我正在使用:

grep "IO resumed after" *

字符串
它显示我所有的文件,这个字符串“IO恢复后”我想把一个更多的参数,将grep所有行“IO恢复后[数>45]秒”

bqucvtff

bqucvtff1#

最好使用awk

awk 'match($0,"IO resumed after") { if (substr($0,RSTART+RLENGTH)+0 > 45) print }' file

字符串
这将搜索字符串“IO recommended after”,如果找到该字符串,它将获取该字符串之后的所有内容并将其转换为数字:如果“IO resumed after”后面的子字符串以数字开头,那么当我们只给它加零时,它将被转换为该数字。
这只在以下情况下有效:

xxxxIO resumed after_nnnnyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy


其中xy是随机字符,下划线是任意空格序列,n是数字。
您可以使用以下命令集测试它:

$ seq 40 0.5 50 | awk '{print "foo IO resumed after",$0,"random stuff"}' \
  | awk 'match($0,"IO resumed after") { if (substr($0,RSTART+RLENGTH)+0 > 45) print }'


其输出:

foo IO resumed after 45.5 random stuff
foo IO resumed after 46.0 random stuff
foo IO resumed after 46.5 random stuff
foo IO resumed after 47.0 random stuff
foo IO resumed after 47.5 random stuff
foo IO resumed after 48.0 random stuff
foo IO resumed after 48.5 random stuff
foo IO resumed after 49.0 random stuff
foo IO resumed after 49.5 random stuff
foo IO resumed after 50.0 random stuff

efzxgjgh

efzxgjgh2#

看来我需要学习awk,直到那时我有一个bash解决方案。如果秒数没有小数点,则为:

while read line; do
    number=${line//*after}
    number=${number//seconds*}
    ((number>45)) && echo $line
done <<< $(grep "IO resumed after" *)

字符串
否则我们必须使用bc

while read line; do
    number=${line//*after}
    number=${number//seconds*}
    case $(bc <<< "$number>45") in 1) echo "$line";; esac
done <<< $(grep "IO resumed after" *)

yeotifhr

yeotifhr3#

您可以使用替代项和重复计数来定义大于45的数字的搜索模式。
此解决方案假定数字是没有小数点的整数。

grep 'IO resumed after \(4[6-9]\|[5-9][0-9]\|[0-9]\{3,\}\) seconds'

字符串
或更短的egrep

egrep 'IO resumed after (4[6-9]|[5-9][0-9]|[0-9]{3,}) seconds'


我用

for i in 1 10 30 44 45 46 47 48 49 50 51 60 99 100 1234567
do
echo "foo IO resumed after $i seconds bar"
done | grep 'IO resumed after \(4[6-9]\|[5-9][0-9]\|[0-9]\{3,\}\) seconds'


哪个打印

foo IO resumed after 46 seconds bar
foo IO resumed after 47 seconds bar
foo IO resumed after 48 seconds bar
foo IO resumed after 49 seconds bar
foo IO resumed after 50 seconds bar
foo IO resumed after 51 seconds bar
foo IO resumed after 60 seconds bar
foo IO resumed after 99 seconds bar
foo IO resumed after 100 seconds bar
foo IO resumed after 1234567 seconds bar


如果数字(可以)有小数点,则难以定义数字**>45的模式,例如45.1的值。
此模式允许小数点或逗号后跟数字,并实现条件
>=**46。

grep 'IO resumed after \(4[6-9]\|[5-9][0-9]\|[0-9]\{3,\}\)\([.,][0-9]*\)\{,1\} seconds'


第二次编辑:
上面的模式不处理可能的前导零。正如用户kvantour在评论中所建议的那样,可以扩展模式来处理这个问题。此外,如果不需要检查seconds部分,则可以省略小数的模式。

= 45的数字的模式,带有可选的前导零:

grep 'IO resumed after 0*\(4[5-9]\|[5-9][0-9]\|[1-9][0-9]\{2,\}\)'

相关问题