我有一個 AV 日志檔案,其中顯示了每個掃描的行程的多個值:名稱、路徑、掃描的檔案總數、掃描時間。該檔案包含數百個這樣的行程條目(下面的示例),對于掃描的檔案總數 和掃描時間,我想排序和列印最高(或最長)的值,以便確定哪些行程正在影響系統。我用 grep 嘗試了各種方法,但似乎只得到一個按數字順序運行的串列,當我真正想說的是行程 id:86,掃描時間(ns):12761174 是最高的,然后是行程 id 25,等等. 希望我的解釋足夠清楚。
Process id: 25
Name: wwww
Path: "/usr/libexec/wwww"
Total files scanned: 42
Scan time (ns): "62416"
Status: Active
Process id: 7
Name: xxxx
Path: "/usr/libexec/xxxx"
Total files scanned: 0
Scan time (ns): "0"
Status: Active
Process id: 86
Name: yyyy
Path: "/usr/libexec/yyyy"
Total files scanned: 2
Scan time (ns): "12761174"
Status: Active
我努力了:
grep -Eo | grep 'Scan time (ns)' '[0-9] ' file | sort
結果是:
file:Scan time (ns): "9391986"
file:Scan time (ns): "9532119"
file:Scan time (ns): "9730650"
file:Scan time (ns): "9743828"
file:Scan time (ns): "9793469"
file:Scan time (ns): "9911768"
我想要實作的是:
Process id 9, Scan time (ns): "34561"
Process id 86, Scan time (ns): "45630"
Process id 25, Scan time (ns): "1256822"
Process id 51, Scan time (ns): "52351290"
Process id 30, Scan time (ns): "90257651"
Process id 19, Scan time (ns): "178764794932"
uj5u.com熱心網友回復:
這是另一種方法。它使用sed和sort:
sed '/^Process id:/h; /^Scan time (ns):/!d; s/"//g; H; x; s/\n/, /' file | sort -k7,7n
注意:我已經洗掉了掃描時間值周圍的雙引號(整數值周圍的雙引號對我來說意義不大)。
uj5u.com熱心網友回復:
用于一次讀取一條記錄(使用perl“段落模式”,使用空白行作為記錄分隔符),提取時間,并按其倒序排序:
$ perl -00 -lne 'm/Scan time \(ns\):\s "(\d )"/ && push @procs, [ $_, $1 ];
END { print $_->[0] for sort { $a->[1] < $b->[1] } @procs }' input.txt
Process id: 86
Name: yyyy
Path: "/usr/libexec/yyyy"
Total files scanned: 2
Scan time (ns): "12761174"
Status: Active
Process id: 25
Name: wwww
Path: "/usr/libexec/wwww"
Total files scanned: 42
Scan time (ns): "62416"
Status: Active
Process id: 7
Name: xxxx
Path: "/usr/libexec/xxxx"
Total files scanned: 0
Scan time (ns): "0"
Status: Active
uj5u.com熱心網友回復:
使用您顯示的示例,請嘗試以下awk代碼。用 GNU 撰寫和測驗awk。
awk '
/^Process id: /{
val=$NF
next
}
/^Scan time \(ns\): "/{
arr[val]=$NF
}
END{
PROCINFO["sorted_in"]="@ind_num_asc"
for(i in arr){
print "Process id " i ", Scan time (ns): " arr[i]""
}
}
' Input_file
uj5u.com熱心網友回復:
在這種情況下,awk RS(輸入記錄分隔符)和FS(輸入欄位分隔符)的組合很有用:
< inpt awk 'BEGIN { RS = ""; FS = "\n" } { print $1 ", " $5 }' | sort -t \" -k2n
- 在開始處理任何事情之前,即在 中
BEGIN,我們設定RSto"",表示記錄由空行分隔,并且FSto"\n",這意味著(在每條記錄中)欄位由換行符分隔;
- 然后我們繼續列印第 1 和第 5 個欄位,中間有一個逗號。
- 最后,將流的每一行解釋為- 分隔
"的欄位串列,我們sortn通常根據第二個欄位 (-k2)。
uj5u.com熱心網友回復:
只需paste:
$ cat file | paste - - - - - - -
Process id: 25 Name: wwww Path: "/usr/libexec/wwww" Total files scanned: 42 Scan time (ns): "62416" Status: Active
Process id: 7 Name: xxxx Path: "/usr/libexec/xxxx" Total files scanned: 0 Scan time (ns): "0" Status: Active
Process id: 86 Name: yyyy Path: "/usr/libexec/yyyy" Total files scanned: 2 Scan time (ns): "12761174" Status: Active
如果我們添加一些格式:
$ cat file \
| paste - - - - - - - \
| awk '{
printf("process id: %s, scan time (ns): %s\n", $3, $15);
}'
process id: 25, scan time (ns): "62416"
process id: 7, scan time (ns): "0"
process id: 86, scan time (ns): "12761174"
這些是 7 個破折號 ( -),因為您的每條記錄都是 7 行(包括空白行)。
破解說明:
paste將所有輸入檔案的第一行連接成一行,然后連接第二行,依此類推。
因此,對于每個輸入檔案,它依次讀取一行并將其添加到當前輸出行。
我們已經將標準輸入作為輸入,7 次。但標準輸入是一個單一的流。
所以paste會這樣做:
- 從輸入 1 讀取第 1 行(標準輸入的第 1 行)
- 從輸入 2 讀取第 1 行(標準輸入的第 2 行)
- ...
- 從輸入 7 讀取第 1 行(標準輸入的第 7 行)
- 將這些行(標準輸入的第 1-7 行)連接為標準輸出的第 1 行
- 從輸入 1 讀取第 2 行(標準輸入的第 8 行)
- ...
- 從輸入 7 讀取第 2 行(標準輸入的第 14 行)
- 將這些行(標準輸入的第 8-14 行)連接為標準輸出的第 2 行
- ...
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/528128.html
