awkを使用した3つのファイルの処理


9

以下のファイルを検討してください。

file1

boo,8,1024
foo,7,2048

file2

foo,0,24,154
noo,0,10,561

file3

24,154,7,1024,0

私が必要なのは、File1に移動して、次のことを確認することです$2==7。trueの場合、取る$1$2$3からファイル1。ここで$1File1File2が等しいかどうかを比較する必要$1あります。trueの場合、私が取らなければならない$3$4File2の中に存在していないこれはFile1、その後、私が行かなければならないFILE3とかどうかを確認$1からFILE3することに等しい$3からFile2の、そして$2からFILE3に等しい$4からFile2の。はいの場合$2File1からかどうかを確認する必要があります等しい$3からFILE3、この条件が真であるならば、私は比較する必要が$3からはFile1$4からFILE3場合は、$3からファイル1以上である$4から、FILE3

次のスクリプトを試しました。

cat [file1] [file2] [file3] | 
awk -F, 
'{if(NF==3)
    {if($2==7){a[$1]=$1; b[$1]=$2; c[$1]=$3}
    }else
        {if(NF==4){if(a[$1]==$1){d[$3]=$3; e[$4]=$4}
                  }else
                        {if(NF==5){if(d[$1]==$1 && e[$2]==$2){print a[$1], b[$1], c[$1], d[$1]}}
                        }
                  }

  }'

望ましい出力は次のとおりです。

foo,7,2048,24,154,1024

回答:


9

それは私のために働きました:

awk -F, 'FNR==1{++f} \
  f==1 && $2==7 {a1[$1]++; a2[$2]=$3; o=$0} \
  f==2 && a1[$1] {o=o","$3","$4; a3[$3]=$4} \
  f==3 && a3[$1] && $2==a3[$1] && a2[$3] && $4<a2[$3] {print o}' \
file1 file2 file3

説明

  • 最初の行(FNR==1{++f})はファイルインデックスをインクリメントして、後で1〜3のファイルを特定します。
  • FILE1:もし$2等号7
    • 配列a1$1インデックスとa2$2インデックスと$3値で埋めます
    • o最初の3つのフィールドを持つ変数(出力)を書き留めます
  • ファイル2:もし$1file2対等$1file1(prevouslyで書かれましたa1
    • を出力変数に追加$3$4ますo
    • 配列a3$3インデックスと$4値で埋めます。
  • file3:次の場合:
    • $1file2s $3(のインデックスa3)と等しい
    • $2file2sと等しい$4(値a3
    • $3file1sに等しい$2(のインデックスa2
    • $4file1sよりも小さい$3(値a2
  • 次に:
    • の値を出力しoます。

(最後を除いて)バックスラッシュは必要ですか?(FNR == 1の代わりに)BEGINFILEはどうですか?
Archemar

@Archemar BEGINFILEとENDFILEはgawkの拡張であるとバックスラッシュをすべて削除することができ、私はより良いreadablilityのために、それらをinseted:あなたは、1つの行にその全部を書くことができますが、それは見栄えではないでしょう
混沌

@chaos、ありがとうございますが、残念ながら常にnullを返します。
Eng7、15年

@ Azizieh7 3つの入力例ファイルを使用して、mawkとgawkでテストしました。私にとってはうまくいきました。別の入力ファイルまたはエンコード/改行を使用していますか?
2015

@ chaos、file3には異なる改行がありますが、これを克服するためにtr -d '\ 015'を使用しています。
Eng7、15年

1

TXRソリューション:

@(repeat)
@id,@val0,@val1
@  (next)
@  (skip)
@id,@nil,@val2,@val3
@  (next)
@val2,@val3,@val0,@val4,@val5
@  (require (< (int-str val4) (int-str val1)))
@  (output)
@id,@val0,@val1,@val2,@val3,@val4
@  (end)
@(end)

実行:

$ txr join.txr file1 file2 file3
foo,7,2048,24,154,1024

しかし、鋭い観察者は、7がコードのどこにも指定されておらず、出力にのみ表示されていることに気付くでしょう。コードは実際にすべてのレコードを通して行進されているからですfile1プリントの一致と制約を満たすすべての組み合わせ。サンプルデータ内の一つだけが有するものであるval0こと7

さらに多くの組み合わせが見つかった場合は、次のような組み合わせに制限できます7

$ txr -Dval0=7 join.txr file1 file2 file3
foo,7,2048,24,154,1024

# how about 6?
$ txr -Dval0=6 join.txr file1 file2 file3
# no output

TXRパターン抽出言語は、変数名の繰り返し、複数のファイルにまたがる、複数行の抽出パターン、非テキスト制約、さらに出力などの埋め込まれた副作用による暗黙的な後方参照との1つの大きなパターンマッチを提供します。 。

受け入れられたAwkソリューションはTXR Lisp awkマクロを慎重に翻訳しました:

(awk (:begin (set fs "," ofs ","))
     (:let o (a1 (hash :equal-based)) (a2 (hash)) (a3 (hash)))
     (t (mf [orf int-str identity])) ;; map those fields to integers, which can be
     ((and (= arg 1) (= [f 1] 7)) (inc [a1 [f 0] 0])
                                  (set [a2 [f 1]] [f 2])
                                  (set o rec))
     ((and (= arg 2) [a1 [f 0]]) (set o `@o,@[f 2],@[f 3]`)
                                 (set [a3 [f 2]] [f 3]))
     ((and (= arg 3)
           [a3 [f 0]]
           (= [f 1] [a3 [f 0]])
           [a2 [f 2]]
           (< [f 3] [a2 [f 2]])) (prn o)))

実行:

$ txr awkit.tl file1 file2 file3
foo,7,2048,24,154

,1024出力に必要な部分が欠けています。オリジナルの「Awk Classic」にはこの動作があります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.