簡體   English   中英

Grep 一個數字大於 45 的字符串

[英]Grep a string with number greater than 45

我在一個目錄中有多個文件。 我想提取 integer 值大於 45 的所有文件中的每一行。

目前,我正在使用:

grep "IO resumed after" *

它向我顯示了該字符串“IO 恢復后”的所有文件

為此最好使用awk

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

這將搜索字符串“IO resumed after”,如果找到該字符串,它將獲取該字符串之后的所有內容並將其轉換為數字:如果“IO resumed after”之后的 substring 以數字開頭,那么它將轉換為當我們只是將零添加到它時,這個數字。

這僅在該行如下所示時才有效:

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

您可以使用替代項和重復計數來定義大於 45 的數字的搜索模式。

此解決方案假定數字是不帶小數點的 integer 數字。

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,\}\)'

看起來我需要學習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" *)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM