ファイルを読み込んで発生するすべてのエントリを検索し、発生間のコンテンツのハッシュを生成します。

ファイルを読み込んで発生するすべてのエントリを検索し、発生間のコンテンツのハッシュを生成します。

次のファイルがあります。

1   Record|1111|ABC
2   text in between for record 1
3   text in between for record 1
4   Record|2222|XYZ
5   text in between for record 2    
6   Record|3333|XYZ
7   text in between for record 3
8   .

このファイルを読み、次のようなものを生成したいと思います。

<Record_number> | <start line> | <number of lines> | md5sum(content)

それは:

1111|1|2|md5sum(Record|1111|ABC\ntext in between for record 1\ntext in between for record 1)
2222|4|1|md5sum(Record|2222|XYZ\ntext in between for record 2\n)

など。

現在、私はこのタスクを実行するために2段階のプロセスを使用しています。

ステップ1:

grep -n -C 0 "Record|" ../test.txt | awk -F[':|'] '{print $3"|"$1}'

作る

1111|1
2222|4
3333|6

ステップ2: このファイルを1行ずつ読み、スクリプトを使用してmd5sumと行番号を生成します。

この2つのステップの問題は、より多くの処理時間を必要とし、ファイルサイズが大きい(〜4 GB)ということです。

もっと良い方法がありますか?

ベストアンサー1

ほとんどはそうかもしれません

awk -F"|" -v OFS="|" '
function md5(lines){
  func="printf \"%s\" \""lines"\"|md5sum|cut -f1 -d\ " ;
  func | getline v;
  return v
}
/Record/{
  if(s>0)
    print r,l,c,md5(line);
  s=1;
  r=$2;
  c=1;
  l=NR;
  line=$0
}
!/Record/{
  line=line"\n"$0;
  c+=1
}
END{
  print r,l,c,md5(line);
}' file

簡単なコード説明:

  1. フィールド区切り記号(入力と出力)を次に変更します。|

  2. 割り当て機能md5(ありがとうピエールオリビエバレセアイデアの場合)適切な入力ラインのmd5sumを計算します。 (より良い方法があるかもしれませんので、コメントをお願いします。)

  3. 単語を含む行の場合は、Record必要なフィールドを変数に入れてカウンタを1で除算し、2番目の単語の発生から始めて、古い形式の行を印刷しますRecord(2番目は最初の印刷、3番目は2番目の印刷)時間など)。

  4. 単語のない行の場合は、変数Recordに自分自身を追加し、カウンターに1を追加してください。linec

  5. 完了したら、最後にフォーマットされた行を印刷します。 (最後の行はメモリに保存され、Record次の単語に出会いましたが、ファイルの終わりに達したときに印刷する必要があるためです。)

おすすめ記事