Respostas:
A resposta abaixo é baseada em perguntas e respostas semelhantes no SO, com algumas modificações relevantes:
$ awk 'FNR==NR {dict[$1]=$2; next} {$2=($2 in dict) ? dict[$2] : $2}1' file2.txt file1.txt
item1 platA
item2 platB
item3 platC
item4 platD
item5 platE
A idéia é criar um mapa de hash com índice e usá-lo como dicionário.
Para a segunda pergunta que você fez no seu comentário (o que deve ser alterado se a segunda coluna de file1.txt
for a sexta coluna ):
Se o arquivo de entrada for como file1b.txt
:
item1 A5 B C D carA
item2 A4 1 2 3 carB
item3 A3 2 3 4 carC
item4 A2 4 5 6 platD
item5 A1 7 8 9 carE
O seguinte comando fará isso:
$ awk 'FNR==NR {dict[$1]=$2; next} {$2=($6 in dict) ? dict[$6] : $6;$3="";$4="";$5="";$6=""}1' file2.txt file1b.txt
item1 platA
item2 platB
item3 platC
item4 platD
item5 platE
Eu sei que você disse awk
, mas há um join
comando para esse fim ...
{
join -o 1.1,2.2 -1 2 -2 1 <(sort -k 2 File1.txt) <(sort -k 1 File2.txt)
join -v 1 -o 1.1,1.2 -1 2 -2 1 <(sort -k 2 File1.txt) <(sort -k 1 File2.txt)
} | sort -k 1
Seria suficiente com o primeiro join
comando se não fosse para esta linha:
item4 platD
O comando basicamente diz: junção com base na segunda coluna do primeiro arquivo ( -1 2
) e na primeira coluna do segundo arquivo ( -2 1
) e gera a primeira coluna do primeiro arquivo e a segunda coluna do segundo arquivo ( -o 1.1,2.2
). Isso mostra apenas as linhas que emparelhadas. O segundo comando join diz quase a mesma coisa, mas diz para mostrar as linhas do primeiro arquivo que não puderam ser emparelhadas ( -v 1
) e gerar a primeira coluna do primeiro arquivo e a segunda coluna do primeiro arquivo ( -o 1.1,1.2
). Depois, classificamos a saída de ambos combinados. sort -k 1
significa classificar com base na primeira coluna e sort -k 2
significa classificar com base na segunda. É importante classificar os arquivos com base na coluna de junção antes de passá-los para join
.
Agora, escrevi a classificação duas vezes, porque não gosto de desarrumar meus diretórios com arquivos, se eu puder ajudar. No entanto, como David Foerster disse, dependendo do tamanho dos arquivos, convém classificá-los e salvá-los primeiro para não ter que esperar para classificar cada um duas vezes. Para dar uma idéia dos tamanhos, eis o tempo necessário para classificar 1 milhão e 10 milhões de linhas no meu computador:
$ ruby -e '(1..1000000).each {|i| puts "item#{i} plat#{i}"}' | shuf > 1million.txt
$ ruby -e '(1..10000000).each {|i| puts "item#{i} plat#{i}"}' | shuf > 10million.txt
$ head 10million.txt
item530284 plat530284
item7946579 plat7946579
item1521735 plat1521735
item9762844 plat9762844
item2289811 plat2289811
item6878181 plat6878181
item7957075 plat7957075
item2527811 plat2527811
item5940907 plat5940907
item3289494 plat3289494
$ TIMEFORMAT=%E
$ time sort 1million.txt >/dev/null
1.547
$ time sort 10million.txt >/dev/null
19.187
São 1,5 segundos para 1 milhão de linhas e 19 segundos para 10 milhões de linhas.
%E
no formato de hora) é menos interessante para medir o desempenho computacional. O tempo de CPU do modo de usuário ( %U
ou simplesmente uma TIMEFORMAT
variável não configurada ) seria muito mais significativo.
%U
.