両方のファイルの一致する列をマージするか、デフォルト値を使用します。

両方のファイルの一致する列をマージするか、デフォルト値を使用します。

ファイルテキストを書き換えようとしています。メインファイル.txt次から変更変更.txt。これメインファイル.txtファイルは次のようになります。

word_1 genre_A
word_2 genre_A
word_3 genre_B
word_4 genre_C
word_5 genre_A

しかも変更.txt次のようになります。

genre_A root_A
genre_C root_C

内容を変更したい変更.txt存在するメインファイル.txt次のようなものを入手してください。

word_1 root_A
word_2 root_A
word_3 genre_B
word_4 root_C
word_5 root_A

このファイルは非常に大きく、自動方法が必要です。

すべての変数をロードしようとしています。変更.txt配列を入れてawk異なる場合は同じ内容を印刷し、同じ場合は変更します。このような:

NR==FNR{a[$1,$2]++;next}  $3==a[$1] {print $1,$2,a[$2]} $3!=a[$1] {print $1,$2,$3}

しかし、私は何かが間違っていた。命令語でも可能だと聞きましたが、join慣れていないので、各部分の説明をしていただければ役に立ちそうです。

みんなありがとうございます。

答え1

コマンドに言及しましたが、joinこの場合は使用するのは簡単ではありません。少なくともそれ自体ではそうではありません。

これら2つのファイルを組み合わせてみましょう。これを行うには、まず結合フィールドでファイルをソートする必要があります。最初のファイルの2番目のフィールドと2番目のファイルの最初のフィールドを使用しますjoin(デフォルト)。

$ sort -k2 -o main.txt main.txt
$ sort -k1 -o changes.txt changes.txt

次に接続します。

$ join -1 2 main.txt changes.txt
genre_A word_1 root_A
genre_A word_2 root_A
genre_A word_5 root_A
genre_C word_4 root_C

我々は行を逃した。もう一度やり直して、無視される行も出力するようにjoin指示します(で何も一致しないため)。main.txtchanges.txt

$ join -1 2 -a 1 main.txt changes.txt
genre_A word_1 root_A
genre_A word_2 root_A
genre_A word_5 root_A
word_3 genre_B
genre_C word_4 root_C

join目的の出力の2番目の列には2つのファイルのデータが混在しているため、2つのファイルのうち特定の列のみを出力する必要はありません。

しかし、上記の出力を使用すると、単純なスクリプトを使用して最後の2つの列を抽出できます(右から列を取得するには、負のフィールド仕様を採用できたらいいですawk!)。cut

$ join -1 2 -a 1 main.txt changes.txt | awk '{ print $(NF-1), $NF }'
word_1 root_A
word_2 root_A
word_5 root_A
word_3 genre_B
word_4 root_C

整列するようにパイプしますsort

$ join -1 2 -a 1 main.txt changes.txt | awk '{ print $(NF-1), $NF }' | sort
word_1 root_A
word_2 root_A
word_3 genre_B
word_4 root_C
word_5 root_A

答え2

アッ注文する:

awk 'NR==FNR {a[$1]=$2;next} {if ($2 in a) print $1,a[$2]; else print $1,$2}' changes.txt main.txt

出力:

word_1 root_A
word_2 root_A
word_3 genre_B
word_4 root_C
word_5 root_A

答え3

タイプそして参加する(しかしアッ)方法:

sort -k2    main.txt >    main_sort.txt ; \
sort -k1 changes.txt > changes_sort.txt ; \
{ join      -i  -1 2 -2 1  -o 1.1 2.2  main_sort.txt changes_sort.txt ; \
  join -v 1 -i  -1 2 -2 1  -o 1.1 1.2  main_sort.txt changes_sort.txt ; } | \
  sort -g | column -t

出力:

word_1  root_A
word_2  root_A
word_3  genre_B
word_4  root_C
word_5  root_A

説明する...

joinソートフィールドを持つ2つのファイルが必要です。各ファイルはサイズが大きく、2回使用する必要があるため、事前に両方のファイルを並べ替える方が効率的です。すべてのファイルが次のようになるとします。商標区切ります。

タイプメインファイル.txt頼る2位分野(ジャンル)、そして変更.txt頼る初めてフィールド(ルート):

sort -k2    main.txt >    main_sort.txt
sort -k1 changes.txt > changes_sort.txt

最初のパスでは、一致するラインを出力します。

join -i -1 2 -2 1 -o 1.1 2.2 main_sort.txt changes_sort.txt

4行出力、を押します土地:

word_1 root_A
word_2 root_A
word_5 root_A
word_4 root_C

join「-1 2 -2 1」言う参加するこれ初めて記録したもの第二到着2位記録したもの最初大地。バナー"-o 1.1 2.2"言う印刷これ初めて記録したもの最初到着2位記録したもの第二大地。

2として使用"-v 1"出力から欠落している行にフラグを立てる最初文書:

join -v 1 -i -1 2 -2 1  -o 1.1 1.2  main_sort.txt changes_sort.txt

出力:

word_3 genre_B

その後、2つの出力が結合されてソートされます(解答の上部を参照)。

関連情報