Remover linhas de arquivos delimitados por tabulações com base em uma coluna comum com outro arquivo

3

Estou tendo problemas para processar um arquivo delimitado por tabulações com base na coluna comum Column_4 com outro arquivo.

Um arquivo provavelmente é muito pequeno (menos de 100 linhas), o segundo, no entanto, será bem mais de 80.000 (ambos com aproximadamente 30 colunas).

file1.txt :

Column_1    Column_2    Column_3    Column_4
A1          B1          C1          D1
A2          B2          C2          D2
A3          B3          C3          D3

file2.txt :

Column_1    Column_2    Column_3    Column_4
Aa1          Bb1          Cc1          Dd1
Aa2          Bb2          Cc2          D2
Aa3          Bb3          Cc3          Dd3

desired_output.txt :

Column_1    Column_2    Column_3    Column_4
Aa2          Bb2         Cc2          D2

Eu tentei uma série de cut , grep , awk etc., mas não consigo acertar.

O objetivo final é remover todas as linhas não correspondentes de file2.txt e comparar a saída a file1.txt .

    
por cmart2112 05.08.2014 / 17:56

2 respostas

4

Se eu entendi bem a sua pergunta, parece um típico join ("Unir linhas em um campo comum") caso de uso:

join --header -j 4 -t $'\t' file1.txt file2.txt

Você recebe 7 colunas para cada linha correspondente.

Aqui está o que eu recebo (para os dados levemente modificados, veja abaixo):

Column_4    Column_1    Column_2    Column_3    Column_1    Column_2    Column_3
D2  A2  B2  C2  Aa2 Bb2 Cc2
D3  A3  B3  C3  Aa3 Bb3 Cc3
D8  A8  B8  C8  Aa8 Bb8 Cc8

(desculpe, as guias não são bonitas aqui):

Coluna_4 é seu valor correspondente e vem em primeiro lugar. Você pode comparar os valores das outras colunas conforme solicitado em seu objetivo .

Se você quiser apenas as colunas da segunda tabela, use:

join --header  -j 4 -o 2.1,2.2,2.3,2.4 -t $'\t' file1.txt file2.txt 

No entanto, join espera que seus arquivos de entrada sejam classificados, então você precisa passá-los por sort e classificá-los no campo 4 primeiro:

join --header  -j 4 -o 2.1,2.2,2.3,2.4 -t $'\t' <(sort -k4 file1.txt) <(sort -k 4 file2.txt)

Para uma demonstração melhor, sugiro arquivos de origem ligeiramente diferentes (hem, isso foi antes de você editá-los)

arquivo1:

Column_1    Column_2    Column_3    Column_4
A0  B0  C0  D0
A2  B2  C2  D2
A3  B3  C3  D3
A8  B8  C8  D8

arquivo2:

Column_1    Column_2    Column_3    Column_4
Aa1 Bb1 Cc1 D1
Aa2 Bb2 Cc2 D2
Aa3 Bb3 Cc3 D3
Aa4 Bb4 Cc4 D4
Aa5 Bb5 Cc5 D5
Aa6 Bb6 Cc6 D6
Aa7 Bb7 Cc7 D7
Aa8 Bb8 Cc8 D8
Aa9 Bb9 Cc9 D9
    
por 05.08.2014 / 20:41
2

Uma solução awk :

$ awk -F"\t" 'FNR==NR{a[$4];next}; $4 in a' OFS="\t" file1 file2
Column_1    Column_2    Column_3    Column_4
Aa2          Bb2          Cc2          D2
    
por 05.08.2014 / 19:12