私はawk、sed、grepなどの経験がありません。私の質問を表現しようとすると予想以上に混乱しているように見えるので、私が達成しようとしている内容の例から始めましょう。
input1
A B C D
A B C
A B C D E F
input2
v A
c B
c C
c D
v E
output
A B C D
v c c c
A B C
v c c
A B C D E F
v c c c v Ø
デフォルトでは2つの入力ファイルがあります。
input1
各行には異なる数のフィールドがあります。
input2
各行には2つのフィールドがあります。
output
各行の位置が必要です。最初に行全体とすべてのフィールドを印刷し、次の行のinput1
場合の2番目のフィールドでoutput
その行の各フィールドの内容を照会します。次に、行の最初のフィールドを印刷するか、内容が 。最後のフィールドまでこれを繰り返し、結果を1行に印刷します。次に、各行に対して同じことを行います。input1
input2
input2
Ø
input2
input1
似ていますが、少し違うことができるので、コマンドの各部分が何をしているのかについて簡単に説明してください。よろしくお願いします。
答え1
$ awk 'FNR == NR { a[$2] = $1; next }
{ print
line = (a[$1] ? a[$1] : "Ø")
for (i = 2; i <= NF; ++i) {
line = line OFS (a[$i] ? a[$i] : "Ø")
}
printf("%s\n", line)
}' input2 input1
A B C D
v c c c
A B C
v c c
A B C D E F
v c c c v Ø
つまり、最初のファイル()から読み取ると、input2
各文字を置き換える必要があるシンボルでルックアップテーブルに入力されます。
2番目のファイル(input1
)を読み取るときに入力行を出力し、フィールドを繰り返してルックアップテーブルの正しいシンボルを使用して文字列を整理します。ルックアップテーブルにシンボルがない場合は、そのシンボルを挿入してくださいØ
。
次に、終了改行文字として組み立てられた文字列を出力します。
これを適切なスクリプトに変換することもできます。
#!/usr/bin/awk -f
FNR == NR { a[$2] = $1; next }
{ print
line = (a[$1] ? a[$1] : "Ø")
for (i = 2; i <= NF; ++i) {
line = line OFS (a[$i] ? a[$i] : "Ø")
}
printf("%s\n", line)
}
次に実行可能にし(chmod +x script
)、次のように実行します。
$ ./script input2 input1
A B C D
v c c c
A B C
v c c
A B C D E F
v c c c v Ø
答え2
これはうまくいくようです:
awk 'NR==FNR { code[$2]=$1 } NR!=FNR {print; for( i=0; i<=NF; i++) { printf( "%s ", code[$i] ) }; printf "\n" }' input2 input1
このNR==FNR
ブロックは、指定された最初のファイル(処理されたレコードの総数が現在までの合計と同じ)でのみ実行され、後の出力に使用される配列を埋めます。
このNR!=FNR
ブロックは後続のファイルでのみ実行され、最初に与えられた入力行を出力し、それを段階的に実行し、各値を配列照会の添字として使用するかどうかを決定しv
ますc
。
この一連の繰り返しの後に改行文字が出力される。