awkが複数のファイルを処理するのに問題があります。

awkが複数のファイルを処理するのに問題があります。

私の入力ファイルにはコロンで区切られたフィールドがあります。

基本:

one:111:222:333
fiv:333:222:333
two:123:234:500

ファイル1:

one:111:222:333
two:123:234:501

ファイル2:

one:111:222:333
thr:-:234:232
fiv:999:500:232

ヒントありがとう協会awkコードをいくつか修正しました。

$ awk -F':' -vf=main 'FILENAME==f{m=$0};FILENAME!=f&&$2~/[0-9]+/{if ($2~/[0-9]+/&&(!($1 in a) || $3 > a[$1])) { a[$1] = $3; b[$1] = $0 } next;}{if (($1 in a) && (a[$1] > $3)){ print b[$1]":updated:"m; delete b[$1] } else print; }' file* main
thr:-:234:232
one:111:222:333
fiv:999:500:232:updated:fiv:333:222:333
two:123:234:500

なぜ行を印刷するのですthr:-:234:232か?thrデフォルトファイルでは何も起こらないので、そのファイルのすべての更新は無視する必要があります。更新は、基本ファイル内の最初の列の行とfile1またはfile2に存在し、3番目の列に大きい値を持つ最初の列に対応する行のみに基づいている必要があります。

ここではなぜ$2~/[0-9]+/動作しませんか?

更新:まだわからない。以下を見てください。

テストメインファイルを次のように変更した場合:

one:111:222:333 fiv:333:222:333 two:123:234:500 ten.233:422:452

そして、次のawkコマンドを実行してください。

$ awk -F':' -vf=main 'FILENAME==f{m=$0};FILENAME!=f&&$2~/[0-9]+/{if ($2~/[0-9]+/&&(!($1 in a) || $3 > a[$1])) { a[$1] = $3; b[$1] = $0 } next;}{if (($1 in a) && (a[$1] > $3)){ print b[$1]":updated:"m; delete b[$1] } else print; }' file* main
thr:-:234:232
one:111:222:333
fiv:999:500:232:updated:fiv:333:222:333
two:123:234:500
ten.233:422:452

したがって、thr行はファイルにthrないため、出力にはならないため、出力が間違っています。main

追加の条件を追加してコマンドを変更しましたが、else if($1 in a) {print}; デフォルトファイルに「ten」で始まる行は印刷されません。

$ awk -F':' -vf=main 'FILENAME==f{m=$0};FILENAME!=f&&$2~/[0-9]+/{if ($2~/[0-9]+/&&(!($1 in a) || $3 > a[$1])) { a[$1] = $3; b[$1] = $0 } next;}{if (($1 in a) && (a[$1] > $3)){ print b[$1]":updated:"m; delete b[$1] } else if($1 in a) {print}; }' file* main
one:111:222:333
fiv:999:500:232:updated:fiv:333:222:333
two:123:234:500

どんな助けでも本当に感謝します。

awkは本当に素晴らしいです。残念ながら、私はプログラマーではないので、まだ自分自身を見つけることができません。

ベストアンサー1

nextブロックに条件があるためですFILENAME != f && $2 ~ /[0-9]+/。行がthrその条件を満たしていないため、「すべての行」ブロックに属します。そこには$ 1が存在しないため、aブロックelseが入力され、対応する行が印刷されます。

私はあなたが実際にプログラムを見ることができるように合理的なインデントを使用している場合、これを自分で理解できると思います。

awk -F':' -vf=main '
    FILENAME == f {m = $0}
    FILENAME != f && $2 ~ /[0-9]+/ {
        if ($2 ~ /[0-9]+/ && (!($1 in a) || $3 > a[$1])) { 
            a[$1] = $3
            b[$1] = $0 
        } 
        next
    }
    {
        if (($1 in a) && (a[$1] > $3)) { 
            print b[$1]":updated:"m
            delete b[$1] 
        } else 
            print
    }
' file* main

おすすめ記事