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”.
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?
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”.
Use awk
:
awk 'NR==FNR{a[$1];next} ($1 in a)' table_1 table_2
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
.
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
Tags grep text-processing awk