0

たとえば、シェルで 2 つのファイルを結合するにはどうすればよいですか。

ファイル1 -

server1          monthly      25
server2          monthly      24
server3          daily        21
server4          weekly       7
server5          weekly       7                                         

ファイル2 -

server1          monthly      5
server2          monthly      4
server3          daily        1
server4          weekly       2

次のような出力を取得するのを手伝ってもらえますか:

server1          monthly      25     5
server2          monthly      24     4
server3          daily        21     1
server4          weekly       7      2
server5          weekly       7      0
4

2 に答える 2

6

これは の仕事ですjoin:

$ join -a 1 -a 2 -e 0 -o '1.1 1.2 1.3 2.3' file1 file2
server1 monthly 25 5
server2 monthly 24 4
server3 daily 21 1
server4 weekly 7 2
server5 weekly 7 0

column -t適切にフォーマットされたテーブルにパイプします。

$ join -a 1 -a 2 -e 0 -o '1.1 1.2 1.3 2.3' file file2 | column -t 
server1  monthly  25  5
server2  monthly  24  4
server3  daily    21  1
server4  weekly   7   2
server5  weekly   7   0

リダイレクト演算子を使用して、これを新しいファイルに保存します。

$ join -a 1 -a 2 -e 0 -o '1.1 1.2 1.3 2.3' file file2 | column -t > newfile

説明:

-a            print unpairable lines from file FILENUM, where FILENUM is
              1 or 2, corresponding to FILE1 or FILE2

-e EMPTY      replace missing input fields with EMPTY

-o FORMAT     obey FORMAT while constructing output line

-aのような行を表示するために使用されserver 5..file1そのような行が見つからない場合は、空のフィールドを に置き換え、出力file2 -e 0を書式設定するために使用されます。 0-o1.1file1 field 11.3file1 field 3

注:joinファイルを最初にソートする必要があるため(この場合はすでにソートされています)、コマンドの使用と組み合わされることがよくありますsort

于 2012-12-14T13:01:13.460 に答える
3

を使用する 1 つの方法を次に示しawkます。

awk 'FNR==NR { a[$1,$2]=$3; next } { print $0, (a[$1,$2] ? a[$1,$2] : "0") | "column -t" }' file2 file1

結果:

server1  monthly  25  5
server2  monthly  24  4
server3  daily    21  1
server4  weekly   7   2
server5  weekly   7   0

説明:

FNR==NR { ... } は、引数リストの最初のファイルにのみ当てはまる構造です。
したがって、最初のファイルでは、列 1 と 2 を配列に追加し、3 番目の列を値として割り当てます。「next」は、入力の次の行を awk に強制的に読み込ませるだけです (したがって、残りのコードの処理をスキップします)
awk が最初のファイルの処理を完了すると、2 番目のファイルに移動します

awk は、2 番目のファイルのすべての行を出力します。この print ステートメントの末尾には、三項演算子と呼ばれる演算子が追加されており、このステートメントは次の形式になっています: ( x ? a : b )
これは単に、if (x) then (a) else (b) という意味です。私は書くことができた:

awk 'FNR==NR { a[$1,$2]=$3; next } { if (a[$1,$2]!=0) print $0, a[$1,$2]; else print $0, "0" }' file2 file1 | column -t

...しかし、三項はセクシーです。

于 2012-12-14T13:21:13.603 に答える