大きなファイルのカウンターフィールドを繰り返し値に置き換える

大きなファイルのカウンターフィールドを繰り返し値に置き換える

約70,000行を含む巨大なテキストファイルがあります。私の目標は、このファイルを読み込み、パターン(「count」)を一致させ、その値を繰り返し数値として追加または置換することです。

私がしていることは:

  1. ファイルをお読みください。
  2. Grepはパターンの数を探します。
  3. 一致するものがある場合、パターンは削除されます。
  4. この行に必要なパターン(Count = $ i)を追加してください。
  5. 増分変数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ため、より高い値も生成されません。

関連情報