grepを使用してログ行の特定の部分のみを出力する

grepを使用してログ行の特定の部分のみを出力する

私はこのような行を持っています -

/mnt/internal-app/logs/internal-app.log_2019-08-21.log.gz:2019-08-21 07:31:14,153 5458142 [XNIO-3 task-4] INFO  c.c.p.i.m.ws.FileManger [FileName.java:1838] - UUIDs in this bucket 8501792126581991569,8073766106536916628,4830289023695906800,6135982080116553120,8306484440313978157,9040948912536460872,8471856544054164043,5431263453539111247,7661719762428556576
/mnt/internal-app/logs/internal-app.log_2019-08-21.log.gz:2019-08-21 07:31:14,153 5458144 [XNIO-3 task-4] INFO  c.c.p.i.m.ws.FileManger [FileName.java:1838] - UUIDs in this bucket 6501792126581991569,8073766106536916628,4830289023695906800,6135982080116553120,8306484440313978157,9040948912536460872,8471856544054164043,5431263453539111247,7661719762428556576

最終的にすべきことは、すべてのUUIDを収集し、次のようにSQL挿入ステートメントを準備することです。

insert into sometable (uuid) values ("6501792126581991569","8073766106536916628")..(..);

そのような行数は500,000に近い。 Sublimeテキストエディタでファイルを開いて正規表現を適用することはできません。

だからgrepを通して試しています。

私はこれを試しました -

zgrep "UUIDs in this bucket" /mnt/internal-app/logs/internal-app.log_2019-08-2* | grep -Eo ".* UUIDs in this bucket(.*)" | cut -d: -f5

必要以上に印刷されます。

1838] - UUIDs in this bucket 8501792126581991569,8073766106536916628,4830289023695906800,6135982080116553120,8306484440313978157,9040948912536460872,8471856544054164043,5431263453539111247,7661719762428556576

UUIDでのみ選択する方法は?

修正する

SQLクエリ構文の変更 -

insert into sometable (uuid) values ("6501792126581991569"),("8073766106536916628")..(..);

答え1

それ以降のすべての数字が必要な場合は、次のように使用UUIDs in this bucketできますsed

$ zcat file.gz | sed -n 's/^.*UUIDs in this bucket //p' 
8501792126581991569,8073766106536916628,4830289023695906800,6135982080116553120,8306484440313978157,9040948912536460872,8471856544054164043,5431263453539111247,7661719762428556576
6501792126581991569,8073766106536916628,4830289023695906800,6135982080116553120,8306484440313978157,9040948912536460872,8471856544054164043,5431263453539111247,7661719762428556576

または、perlを使用してSQL文全体を印刷します。

$ zcat file.gz | perl -ne 'chomp;if(s/^.*UUIDs in this bucket //){@uuids=split(/,/); $k{$_}++ for @uuids} END{ print "insert into sometable (uuid) values (" , join ",",map{qq/"$_"/} keys(%k); print ");\n"}' 
insert into sometable (uuid) values ("6135982080116553120","4830289023695906800","8501792126581991569","9040948912536460872","7661719762428556576","8471856544054164043","8306484440313978157","6501792126581991569","5431263453539111247","8073766106536916628");

または少し明確です。

$ zcat file.gz | 
    perl -ne 'chomp;
              if(s/^.*UUIDs in this bucket //){
                @uuids=split(/,/); 
                $k{$_}++ for @uuids
              }
              END{
                print "insert into sometable (uuid) values (" , 
                           join ",",map{qq/"$_"/} @uuids; 
                print ");\n"
            }'
insert into sometable (uuid) values ("6501792126581991569","8073766106536916628","4830289023695906800","6135982080116553120","8306484440313978157","9040948912536460872","8471856544054164043","5431263453539111247","7661719762428556576");

答え2

他のツールを使用する意思がある場合、または可能であれば、常に行末を望むように見えるので、grepかなり簡単に実行できます。awkたとえば、最後のフィールドのみを印刷することができます。

zcat /mnt/internal-app/logs/internal-app.log_2019-08-2* | awk '/UUIDs in this bucket/ {print $NF}'

zgrepPerlスタイルの正規表現をサポートしていない形式があるかどうかはわかりませんが、あなたの形式がサポートしていると仮定すると、次のことができます。

zgrep -Po 'UUIDs in this bucket \K.*' /mnt/internal-app/logs/internal-app.log_2019-08-2*

なぜなら、\Kパターンはマッチングの一部として以前のすべてを計算しないように指示するからです。したがって、これは試合後に起こったことだけを印刷します。

答え3

perlSQLコードを生成する別の方法:

zcat -f /mnt/internal-app/logs/internal-app.log_2019-08-2* |
  perl -lne 'BEGIN{$"=q(",")}
             @u = m{(?:UUIDs in this bucket |\G,)\K\d+}g;
             print qq(insert into sometable (uuid) values ("@u");) if @u'

関連情報