他のファイルの最初の列の比較 [閉じる]

他のファイルの最初の列の比較 [閉じる]

同じディレクトリにある他のファイルとファイルを比較したいです。

file1.txt含む:

move 34#123#    
get 11#278    
put 33#29#567#23

file1.txtファイル1.txt2.txt

1.txt含む:

move 11    
put 34    
run 13

2.txt含む:

get 14    
move 66

私に必要な結果は次のとおりです。

move 2    
get 1    
put 1

どうすればいいですか?

答え1

解決策は次のとおりですawk

$ awk 'FNR==NR{a[$1];next}($1 in a){++a[$1]}
    END{for(i in a){print i" "a[i]}}' file1.txt 1.txt 2.txt
put 1
get 1
move 2

説明する

  • FNR==NR{a[$1];next}file1.txt:処理中に関連配列に発生項目を表示します。$1a
  • ($1 in a){++a[$1]}:sumを処理するときに1.txt連想配列に存在することを2.txt確認し、存在する場合は数に1を加えます。$1a
  • 最後に、連想配列を繰り返して、aキー(ファイルの最初のフィールド)とその値(1.txt合計で発生した回数2.txt)を印刷します。

perl同じロジックを使用する別の解決策は次のとおりです。

$ perl -alne '++$i;                  
    if ($. == $i) {
        $h{$F[0]}=0;
        close ARGV if eof;
        next;
    }
    ++$h{$F[0]} if defined $h{$F[0]};
END {
    for (keys %h) {
        print $_." ".$h{$_};
    }
}' file1.txt 1.txt 2.txt
move 2
get 1
put 1

答え2

grep、、、、 &などawksortさまざまなツールを使用して選択肢を表示しますuniq。もちろん、より多くのツールを使用していますが、AWKより何が起こっているのかを理解するのは簡単です。

$ for i in 1.txt 2.txt; do grep -f <(awk '{print $1}' $i) file1.txt; done | \
    awk '{print $1}' | sort | uniq -c

はい

$ for i in 1.txt 2.txt; do grep -f <(awk '{print $1}' $i) file1.txt; done | \
    awk '{print $1}' | sort | uniq -c
      1 get
      2 move
      1 put

どのように動作しますか?

以下は少し拡張された例です。

$ for i in 1.txt 2.txt; do 
    grep -f <(awk '{print $1}' $i) file1.txt
  done | \
    awk '{print $1}' | sort | uniq -c

このforループは、一致させたい2つのファイルを繰り返します1.txt。繰り返すたびに、ターゲットファイル内の2.txtファイルの1つの最初の列を静的文字列セットとして使用します。grepfile1.txt

$ grep -f <(awk '{print $1}' $i) file1.txt

ループ内の各ファイルに対してコマンドを実行した後、すべてのfor出力を取得し、その中の最初の列のみを選択します。

move
put
move
get

次に、sortsumを使用して、私uniqたちが見る各タイプの数を計算します。

答え3

別のアプローチは次のとおりですjoin

join -1 1 -2 2 -o 0 2.1 <(sort -k1,1 file1.txt) <(cut -d ' ' -f1 1.txt 2.txt | sort | uniq -c)

出力は次のようにソートされます。

get 1
move 2
put 1

file1.txtたとえば、注文を維持したい場合

move 2
get 1
put 1

以下を実行できます。

join -j2 -o 1.1 0 2.1 <(nl -ba -nrz file1.txt | sort -k2,2) \
<(cut -d ' ' -f1 1.txt 2.txt | sort | uniq -c) | sort -k1 | cut -d ' ' -f2-

関連情報