Como canalizar uma saída de uma lista como a entrada do grep no Linux?

0

Eu tenho um table_1

A D G
B E H
C F I

Eu imprimo a coluna 1 da tabela acima usando awk '{print $1}' table_1 para obter list_1

A
B
C

Eu quero usar list_1 acima para grep -f de table_2

A n m
B m n
C n m
D m n
E n m

para obter table_3

A n m
B m n
C n m

mas eu quero fazer isso usando um one-liner, não precisando salvar um arquivo intermediário de list_1 .

Como posso estruturar o comando?

    
por Johnny Tam 01.02.2018 / 06:45

4 respostas

3

Uma variação trivial (mas não bash-specific) no comentário do Cyrus :

awk '{print $1}' table_1 | grep -f - table_2

que usa a convenção generalizada de que um nome de arquivo de - significa “lido a partir da entrada padrão”.

    
por 01.02.2018 / 08:34
2

Use awk :

awk 'NR==FNR{a[$1];next} ($1 in a)' table_1 table_2
    
por 01.02.2018 / 08:00
1

Esta é outra maneira de usar join . Se os arquivos estiverem classificados e table_2 tiver apenas três colunas, você pode usar

join -o "2.1 2.2 2.3" table_1 table_2 > table_3

Como Kusalananda diz , join é um programa que existe especificamente para combinar dois arquivos combinando valores de uma coluna do primeiro arquivo contra valores de uma coluna do segundo arquivo. Por padrão, se usa a primeira coluna de cada arquivo (você pode sobrescrever isso). Por padrão, combina as linhas correspondentes, assim:

$ join table_1 table_2
A D G n m
B E H m n
C F I n m

O -o "2.1 2.2 2.3" diz "saída do primeiro campo do segundo arquivo, e depois o segundo campo do segundo arquivo, e, em seguida, o primeiro terço do segundo arquivo (mas nada do primeiro arquivo 1 ) ”. Infelizmente, parece que não há atalhos, abreviações aceleradores ou curingas aqui; não há como dizer "imprima a linha inteira do segundo arquivo". Se o segundo arquivo tiver muitos campos, então o formato -o terá que ser muito longo.

Isso difere das soluções grep (você e meu ) na medida em que corresponde especificamente aos valores da coluna 1 de table_1 contra os valores da coluna 1 de table_2 , e não lhe dará linhas de table_2 que têm A na coluna2 ou coluna3 ou AZ na coluna1. join , como grep , reconhece uma opção -i ( --ignore-case ) então, se a primeira linha de table_2 for a n m (com minúscula a ), você obterá essa linha na sua saída table_3 if (e somente if) você especifica -i .

por 01.02.2018 / 10:37
0

Supondo que ambas as tabelas estão classificadas na primeira coluna e usando um shell como bash ou ksh93 que entende a substituição de processo por <(...) :

$ join <( awk '{ print $1 }' table_1 ) table_2
A n m
B m n
C n m

Se as tabelas não forem classificadas, precisamos classificá-las:

$ join <( awk '{ print $1 }' table_1 | sort ) <( sort table_2 )
A n m
B m n
C n m

O utilitário join realiza uma operação relacional INNER JOIN na primeira coluna (por padrão ) dos dois arquivos que você fornece.

Redirecionar a saída para um novo arquivo para criar table_3 :

$ join <( awk '{ print $1 }' table_1 | sort ) <( sort table_2 ) >table_3
    
por 01.02.2018 / 10:02