我需要根據在第一列中找到的 id 將一個大的日志檔案拆分成較小的檔案,這個解決方案在幾個月內創造了奇跡并且非常快:
awk -v dir="$nome" -F\; '{print>dir"/"dir"_"$1".log"}' ${nome}.all;
其中 $nome 是檔案和目錄名稱。
它非常快并且一直作業到日志檔案達到幾百萬行 2GB文本檔案,然后它開始顯示
"Too many open files"
解決方法確實很簡單,加上close命令:
awk -v dir="$nome" -F\; '{print>dir"/"dir"_"$1".log"; close(dir"/"dir"_"$1".log")}' ${nome}.all;
問題是,現在它非常慢,它需要永遠做一些在幾秒鐘內完成的事情,我需要優化它。
AWK不是強制性的,我可以使用替代方案,我只是不知道如何
uj5u.com熱心網友回復:
未經測驗,因為您沒有提供任何示例輸入/輸出進行測驗,但應該這樣做:
sort -t';' -k1,1 "${nome}.all" |
awk -v dir="$nome" -F\; '$1!=prev{close(out); out=dir"/"dir"_"$1".log"; prev=$1} {print > out}'
你的第一個腳本:
awk -v dir="$nome" -F\; '{print>dir"/"dir"_"$1".log"}' ${nome}.all;
有3個問題:
- 它沒有在您進行時關閉檔案名,因此超出了您看到的閾值。
- 它在輸出重定向的右側有一個未加括號的運算式,這是每個 POSIX 未定義的行為。
- 它沒有
${nome}在檔案名中參考 shell 變數。
你的第二個腳本:
awk -v dir="$nome" -F\; '{print>dir"/"dir"_"$1".log"; close(dir"/"dir"_"$1".log")}' ${nome}.all;
雖然現在關閉輸出檔案名,但仍然有問題 2 和 3,然后添加了 2 個新問題:
- 它在每個輸入行打開和關閉輸出檔案一次,而不是僅在必須更改輸出檔案名時。
- 它為寫入它的每一行覆寫每個 $1 的輸出檔案,而不是附加到它。
以上假設每個 $1 有多行輸入,因此每個輸出檔案將有多行。否則,您在關閉輸出檔案時看到的減速不會發生。
上面sort可以重新排列每個 $1 的輸入行的順序。如果這是一個問題-s,如果您有 GNU 排序,請添加“穩定排序”,或者讓我們知道,因為使用 POSIX 工具很容易解決。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/430762.html
