約70,000行を含む巨大なテキストファイルがあります。私の目標は、このファイルを読み込み、パターン(「count」)を一致させ、その値を繰り返し数値として追加または置換することです。
私がしていることは:
- ファイルをお読みください。
- Grepはパターンの数を探します。
- 一致するものがある場合、パターンは削除されます。
- この行に必要なパターン(Count = $ i)を追加してください。
- 増分変数i。
これはコードです
line_count=0
i=0
while read line
do
line_count=$((line_count+1))
if echo "$line" | grep -q "Count"
then
sed -i "$line_count d" /tmp/$rand_file1
sed -i "$line_count i Count = $i" /tmp/rand_file1
i=$((i+1))
fi
done </tmp/rand_file1
上記の技術を完了するのに約25分かかります。より大きなデータファイルを処理するので、この時間を短縮する方法はありますか?
入力スキーマとファイルと予想される出力は次のとおりです。
入力ファイル
Count
Name = Sarah
ID = 113
PhNo =
Count
Name = John
ID = 787
PhNo =
Count = 123
Name = Mike
ID = 445
PhNo =
Count Now
Name = Max
ID = 673
PhNo =
期待される出力ファイル
Count = 1
Name = Sarah
ID = 113
PhNo =
Count = 2
Name = John
ID = 787
PhNo =
Count = 3
Name = Mike
ID = 445
PhNo =
Count = 4
Name = Max
ID = 673
PhNo =
答え1
シェルからテキストファイルを解析する非常に遅くてエラーが発生しやすい。grep
入力ファイルの各行とインクルードごとsed
に1回実行しますCount
。
私が知る限り、これは次のように置き換えることができます。
awk '$1 == "Count" { printf("Count = %d\n", ++i); next } { print }' rand_file1 >rand_file1.new
Count =
最初のフィールドがある行に達すると、正しい増分で行を出力し、Count
他のすべての行はそのまま渡します。
または、
awk '$1 == "Count" { $0 = sprintf("Count = %d", ++i) } { print }' rand_file1 >rand_file1.new
値(入力行)を修正$0
し、単一print
。
最後の変形は次のように短縮できます。
awk '$1 == "Count" { $0 = sprintf("Count = %d", ++i) } 1' rand_file1 >rand_file1.new
皆さんも見てください」シェルループを使用してテキストを処理するのはなぜ悪い習慣と見なされますか?」。
答え2
必須のperl
回答:
perl -pe 's{^Count\b.*}{"Count = " . ++$i}e'
答え3
短いawk
方法:
awk '$1 == "Count"{ $0 = "Count = "++i }1' file
出力:
Count = 1
Name = Sarah
ID = 113
PhNo =
Count = 2
Name = John
ID = 787
PhNo =
答え4
を使用sed
してseq
パイプ入力を繰り返します。
t='Count'
seq -f "$t = %g" 70000 | sed -i -e "/^$t/R /dev/stdin" -e "/^$t/d" /tmp/rand_file1
メモ:
sed
~のR
電子ヘッド中かっこ内ではコマンドが機能しないため、{}
2-e
つが必要です。70000
十分に大きい数字かもしれません。sed
停止すると停止するseq
ため、より高い値も生成されません。