AWKまたはスクリプトによるテキスト処理による大容量ファイルの管理

AWKまたはスクリプトによるテキスト処理による大容量ファイルの管理

@Ed Mortonに返信、

入力する

...
useless_words Number_100 : Message xx Dublin xx Paris useless_words -Code 452 useless_words
useless_words Number_100 : Rename message (old 452 ; new 557)
useless_words Number_100 : Message xx Dublin xx Paris useless_words -Code 557 useless_words
useless_words Number_101 : Message xx Toronto xx Rio useless_words -Code 842 useless_words
useless_words Number_102 : Message xx Rome xx Moscow useless_words -Code 432 useless_words
useless_words Number_103 : Message from Dublin to Paris -Code 557
useless_words Number_103 : Error Message
...
useless_words Number_110 : Message xx Alger xx Barcelona useless_words -Code 345 useless_words
useless_words Number_110 : Rename message (old 345 ; new 846)
useless_words Number_110 : Message xx Alger xx Barcelona useless_words -Code 846 useless_words
useless_words Number_111 : Message xx Mexico xx Dallas useless_words -Code 498 useless_words
useless_words Number_112 : Rename message (old 432 ; new 245)
...
useless_words Number_115 : Message from Alger to Barcelona -Code 846
useless_words Number_115 : Error Message
...

出力

useless_words Number_100 : Message xx Dublin xx Paris useless_words -Code 452 useless_words
useless_words Number_100 : Message xx Dublin xx Paris useless_words -Code 557 useless_words
useless_words Number_100 : Message from Dublin to Paris -Code 557
useless_words Number_110 : Message xx Alger xx Barcelona useless_words -Code 345 useless_words
useless_words Number_110 : Message xx Alger xx Barcelona useless_words -Code 846 useless_words
useless_words Number_110 : Message from Alger to Barcelona -Code 846

これを行うには、次の手順に従ってください。

    1. エラーメッセージを含む行と一致します=>メッセージ番号を取得します(ここではNumber_103とNumber_115)。
    1. 数字(Number_103とNumber_115)を含む行を検索し、3つの単語を選択します(この場合は$ 6 $ 8 $ 10 => Dublin Paris 557; Alger Barcelona 846)。私はその行を印刷します。最初のメッセージを受け取りました。
    1. これらの3つの単語に一致する行を検索し、メッセージ番号(ここではNumber_100とNumber_110)を書き留めます。この行を印刷します。 2回目のメッセージを受け取りました。
    1. 最後に印刷されたメッセージ(ここではNumber_100とNumber_110)と同じメッセージ番号を持つ名前が変更されたメッセージを検索し、前のキー(ここでは345と452)を取得します。
    1. 前のキー(ここでは345と452)とメッセージ番号(ここではNumber_100とNumber_110)で印刷する最後のメッセージを検索します。
    1. 印刷された最初のメッセージのメッセージ番号を変更します(番号_103 ->番号_100;番号_115 - >番号_110)。

私が書いたこと

#!bin/bash
            
    grep -B1 'Error' inputs.txt |sed '/^-/d' | sed '/^$/d' | grep -v Error >> tmp_01.txt
    
    while read line
    do  
    
    read a b c <<< $(echo $line | cut -d' ' -f6,8,10)
    
    awk -v a1="$a" -v a2="$b" -v a3="$c" '$0~a1 && $0~a2 && $0~a3' inputs.txt >> tmp_02.txt
    
    done < tmp_01.txt
    
    awk '{++i} i==1 {a=$2} i==2 {$2=a; i=0} 1' tmp_02.txt
    
    rm -f tmp_*.txt

わかりました。

useless_words Number_100 : Message xx Dublin xx Paris useless_words -Code 557 useless_words
useless_words Number_100 : Message from Dublin to Paris -Code 557
useless_words Number_110 : Message xx Alger xx Barcelona useless_words -Code 846 useless_words
useless_words Number_110 : Message from Alger to Barcelona -Code 846

コードをすぐに取得しようとしました。 Bodoの助けのおかげです!

実際、BOXに送信されたメッセージは別の場所に送信されました(番号は同じです_)。

useless_words Number_100 : Message xx Dublin xx Paris useless_words -Code 452 useless_words

useless_words Number_100 : Rename message (old 452 ; new 557)

useless_words Number_100 : Message xx Dublin xx Paris useless_words -Code 557 useless_words

その後、ACKをBOX(別の番号_)として送信しました。

useless_words Number_103 : Message from Dublin to Paris -Code 557

通常、BOXから受信したこのACKは他のBOXに送信されますが、時々このACKがブロックされる場合があり、エラーメッセージが表示される場合も同様です。

useless_words Number_103 : Error Message

ベストアンサー1

修正された質問とコメントで要求されたように、この回答は追加の問題を修正せずに質問のスクリプトと同じ結果を生成するより速いスクリプトを作成しようとします。

提案されたスクリプトは、エラーメッセージの数に関係なく、入力ファイルを2回だけ処理します。

しかし、これが質問に示されている出力を得るために修正するより良い基盤であるかどうかはわかりません。 (「まずは動作させて、素早く作らないで、その逆もしないでください」というルールがあります。)

grep -B1 'Error' file.txt |sed '/^-/d' | sed '/^$/d' | grep -v Error| awk '{printf "/%s/ && /%s/ && /%s/\n", $6, $8, $10}' > filter.awk
awk -f filter.awk file.txt

awkまたはスクリプトをファイルに書き込まないでください。

awk -f <(grep -B1 'Error' file.txt |sed '/^-/d' | sed '/^$/d' | grep -v Error| awk '{printf "/%s/ && /%s/ && /%s/\n", $6, $8, $10}') file.txt

またはいいえ(そして入力例には不要と思われるgrep同等のコマンドはありません)sed

awk -f <(awk '/Error/ && prev {$0=prev;printf "/%s/ && /%s/ && /%s/\n", $6, $8, $10;next} {prev=$0}' file.txt) file.txt

おすすめ記事