次のファイルを検討してください。
file1
:
boo,8,1024
foo,7,2048
file2
:
foo,0,24,154
noo,0,10,561
file3
:
24,154,7,1024,0
私が必要なのは行きます。ファイル1そして$2==7
trueであることを確認し$1
て、$2
$3
ファイル1;今比較する必要があります$1
。ファイル1$1
と同じファイル2;事実なら、私は$3
次のことをしなければなりません。$4
ファイル2には存在しませんファイル1、それから出なければならないファイル3そして$1
それが出ていることを確認してくださいファイル3$3
と同じファイル2、$2
そしてファイル3$4
と同じファイル2;そうであれば、私が送ったものであることを確認する必要があります$2
。ファイル1$3
と同じファイル3、この条件が true の場合は$3
比較する必要があります。ファイル1$4
とともにファイル3、$3
ファイル1$4
よりファイル3。
次のスクリプトを試しました。
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
答え1
これは私にとって効果的です。
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のファイルを決定します。 - ファイル1:もし
$2
同じなら7
a1
$1
インデックス、a2
インデックス$2
、$3
値で配列を埋めるo
変数の最初の3つのフィールドを作成する(出力)
- ファイル2:等しい
$1
(file2
以前に作成された)$1
file1
a1
- 出力変数に
$3
合計を追加します。$4
o
a3
$3
インデックスと値で配列を埋めます$4
。
- 出力変数に
- ファイル3:場合:
$1
file2sと同じ$3
(インデックスa3
)$2
file2sと同じ$4
(値a3
)$3
file1sと同じ$2
(インデックスa2
)$4
file1sの下$3
(値a2
)
- それから:
- 印刷された値です
o
。
- 印刷された値です
答え2
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パターン抽出言語は、複数行の抽出パターンと、非テキスト制約、出力などの挿入された副作用を使用して複数のファイルにわたって変数名を繰り返すことで、暗黙の逆参照と一致する大規模なパターンを提供します。
慎重に翻訳されたTXR Lisp awkソリューションを受け入れてください。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」にはこの動作がありました。