web-dev-qa-db-ja.com

ファイル2とファイル3の両方でもファイル1に存在するレコードを検索します

file1.txtfile2.txtfile3.txtの3つのファイルがあり、それらは同じ形式です。

列2と列3に基づいてfile1.txtfile2.txtの両方に存在するfile3.txtから、出力ファイルout.txtのレコードを選択したいと思います。

また、追加の列(out2.txtの列4、file2.txtの列5)を使用して別のファイルfile3.txtを作成する必要があります。

サンプル入力:

file1.txt

1. abc 1 a f11 f13 f14 
2. abd 2 b f12 f14 f13  
3. abe 4 d f13 f16 f12 
4. acf 6 s f14 f15 f19

file2.txt

 1. abc 1 a f21 f23 f24 
 2. abd 1 b f21 f24 f23  
 3. abe 4 d f24 f26 f22 
 4. acf 6 s f23 f25 f29

file3.txt

 1. abc 1 a f31 f33 f34 
 2. abd 2 b f31 f34 f33  
 3. acf 5 s f33 f35 f39 
 4. abe 4 d f34 f36 f32

必要な出力

out.txt

 1. abc 1 a f11 f13 f14 
 2. abe 4 d f13 f16 f12 

out2.txt

 1. abc 1 a f11 f13 f14 f21 f31
 2. abe 4 d f13 f16 f12 f24 f34
1
Prradep

awkで考えられる解決策(正確な要件は何かがあなたの質問から少し不明確なので、必要に応じて編集します):

awk 'FILENAME == ARGV[1] {
    m[$2,$3] = 0; z[$2,$3] = $5;
    next; 
}
FILENAME == ARGV[2] {
    if (($2,$3) in m) {
        m[$2,$3] = 1;
        z[$2,$3] = $5 " " z[$2,$3];
    }
    next;
}
{
    if (($2,$3) in m && m[$2,$3] == 1) {
        print $0 >"out.txt";
        print $0 " " z[$2,$3] >"out2.txt";
    }
}' file3.txt file2.txt file1.txt

3番目のファイルを読み取り、列2と3のキーを持つ2つの配列を作成します。最初の配列はゼロで埋められ、2番目の配列はファイルout2.txtに必要な値です。次に、2番目のファイルを読み取り、列2と3のキーが最初の配列に存在するかどうかを確認します。存在する場合は、値を0から1に変更し、ファイルout2.txtの2番目の配列に必要な値を連結します。最後に、最初のファイルを読み取り、既存のキーを確認し、ファイルout.txtおよびout2.txtに興味深い値を出力します。

out.txt 含める必要があります:

1. abc 1 a f11 f13 f14
3. abe 4 d f13 f16 f12

out2.txt 含める必要があります:

1. abc 1 a f11 f13 f14 f21 f31
3. abe 4 d f13 f16 f12 f24 f34
2
taliezin

あなたはこれをチェックしたいかもしれません site このプログラムでdiff3についてあなたはサンプル出力として3つのファイルを比較することができます:

$ diff3 parent.txt your.txt mine.txt

 ==== 

1:1,2c Hello, 

This is parent file.

2:1,2c Hello, 

This is your file. 

3:1,2c Hello, 

This is my file.

あなたが使用することができます

diff3 file1.txt file2.txt file3.txt > output.txt
3
TheRealProcyon

すべてのファイルで共有回線を選択するには、grepout.txt)を使用できます

grep -ho ' [0-9] [a-z] ' file3 | grep -Fof - file2 | grep -Ff - file1

操作可能なフィールド(バリアントcut -d' ' -f3,4 file3として)を選択し、それを使用して次のfile2およびfile1で検索します。

2つのファイルを結合する場合は通常どおり、joinコマンドを使用します(驚きです!)(out2.txt

join -j 3 <(sort -k3,4 file1 | sed 's/ /+/3') \
          <(join -j 3 <(sort -k3,4 file2 | sed 's/ /+/3') \
                      <(sort -k3,4 file3 | sed 's/ /+/3') \
                      -o '1.4 2.4 1.3') \
          -o '1.1,1.2,1.3,1.4,1.5,2.1,2.2' | sed 's/+/ /'

したがって、3番目と4番目のフィールドを一緒に操作するには、それを連結する必要があります(たとえば、+記号によって)。 joinはソートされた行でのみ動作するため、3番目と4番目のフィールドでsortを実行します。
最初にfile2file3を結合します。その後、結果はfile1と結合され、+記号をsedで削除します。

3
Costas