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

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

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

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次の単語に出会いましたが、ファイルの終わりに達したときに印刷する必要があるためです。)

答え2

Costasの回答に基づいています。

1) 次の内容で parse.awk ファイルを作成します。

/^Record/ {
  if (s>0) {
    printf ("%s|%s|", r,l)
    system("echo '"line"' | md5sum - | awk '{print $1}' ");
  }
  s=1;
  r=$2;
  c=1;
  l=NR;
  line="$0";
}
!/^Record/ {
  line=line"\n""$0";
  c+=1
}
END {
  printf ("%s|%s|", r,l)
  system("echo '"line"' | md5sum - | awk '{print $1}' ");
}

Costasの説明を参照してください。スクリプトは、md5と改行を印刷するためにprintf結果行の先頭のみを実行します(印刷ではなく、改行を入れる)。 system(echo $line | md5sum)

2) 走るawk -F"|" -f parse.awk myfile

3)結果をお楽しみください:

1111|1|cb36533781d8dd00011a85b0db9b87b3
2222|4|521331bb249e8a668afa2199fa8d289a
3333|6|6c2564464187094e9db3159d26ade2a5

関連情報