列のパターンを置き換える

列のパターンを置き換える

入力で他のファイルのファイルパターンを置き換える必要があります。

file1 の内容を想定します。

ab 10
bc 20
cd 30
de 40

ファイル2:

server1;10 feb 2020;disk5;123455678;comment;10;1;desc;abcde3;987654
server1;10 feb 2020;disk6;123455678;comment;10;7;desc;abcde3;987654
server1;10 feb 2020;disk10;123455678;comment;20;4;desc;abcde3;987654
server1;10 feb 2020;disk1;123455678;comment;30;5;desc;abcde3;987654
server1;10 feb 2020;disk9;123455678;comment;20;4;desc;abcde3;987654
server1;10 feb 2020;disk2;123455678;comment;40;6;desc;abcde3;987654
server1;10 feb 2020;disk5;123455678;comment;30;8;desc;abcde3;987654

ここでは、;file2の区切り文字で、列6をfile1の一致する値に置き換えたいと思います。

つまり

server1;10 feb 2020;disk5;123455678;comment;**ab**;1;desc;abcde3;987654

awk/を介して動作することを知っていますsed。助けてもらえますか?注:私たちはawk/sedのGNUバージョンをAIX

答え1

$ 6の値がすべてfile1に含まれているとします。

awk 'FNR == NR {T[$2] = $1; next} {$6 = T[$6]} 1' file1 FS=";" OFS=";" file2

答え2

この練習の難しさは、同じプログラムawkでさまざまなフィールド区切り文字を処理する方法です。

GNUの使用awk:

$ gawk 'FNR == NR { pat[$2] = $1; next } ($6 in pat) { $6 = pat[$6] } { print } ENDFILE { OFS = FS = ";" }' file1 file2
server1;10 feb 2020;disk5;123455678;comment;ab;1;desc;abcde3;987654
server1;10 feb 2020;disk6;123455678;comment;ab;7;desc;abcde3;987654
server1;10 feb 2020;disk10;123455678;comment;bc;4;desc;abcde3;987654
server1;10 feb 2020;disk1;123455678;comment;cd;5;desc;abcde3;987654
server1;10 feb 2020;disk9;123455678;comment;bc;4;desc;abcde3;987654
server1;10 feb 2020;disk2;123455678;comment;de;6;desc;abcde3;987654
server1;10 feb 2020;disk5;123455678;comment;cd;8;desc;abcde3;987654

ここでは、最初のファイルの読み取りを開始し、pat後で列6で置き換えたい内容で連想配列を埋めます。キーは私たちが置き換えるものであり、値は私たちが置き換えるものです。

GNUはawkファイルの読み込みが完了するとENDFILEブロックがあれば実行します(BEGINFILE場合によっては便利なブロックもあります)。 「ファイルローカル」とブロックENDFILEに似ています。BEGINFILEBEGINEND

ここでは、ENDFILE入力フィールドと出力フィールドの区切り文字をセミコロンに変更します。

2番目のファイルを読み取るときに6番目のフィールドのデータをキーとして使用できるかどうかを簡単にテストし、patその場合はその値をそのキーの値に置き換えます。 2番目のファイルのすべての行は、変更されたかどうかに関係なく印刷されます。

GNUでない場合は、awk次のことができます。

$ awk 'FNR == NR { pat[$2] = $1; next } { OFS = FS = ";"; $0=$0 } ($6 in pat) { $6 = pat[$6] } { print }' file1 file2
server1;10 feb 2020;disk5;123455678;comment;ab;1;desc;abcde3;987654
server1;10 feb 2020;disk6;123455678;comment;ab;7;desc;abcde3;987654
server1;10 feb 2020;disk10;123455678;comment;bc;4;desc;abcde3;987654
server1;10 feb 2020;disk1;123455678;comment;cd;5;desc;abcde3;987654
server1;10 feb 2020;disk9;123455678;comment;bc;4;desc;abcde3;987654
server1;10 feb 2020;disk2;123455678;comment;de;6;desc;abcde3;987654
server1;10 feb 2020;disk5;123455678;comment;cd;8;desc;abcde3;987654

これは少し非効率的ですが、2番目のファイルの各行に合計を設定し、OFS入力をFS再分割することです。;

やや効率的ですが、まだ見苦しいバリエーションは、2番目のファイルの最初の行だけを設定することですOFSFS

awk 'FNR == NR { pat[$2] = $1; next } FS != ";" { OFS = FS = ";"; $0=$0 } ($6 in pat) { $6 = pat[$6] } { print }' file1 file2

関連情報