Dados os arquivos:
1.txt
1, abc, 123, 456, 789
2, lmn, 123, 456, 789
3, pqr, 123, 456, 789
2.txt
1, abc, 123, 000, 000
3, lmn, 123, 000, 000
9, opq, 123, 000, 000
SAÍDA.txt
ID, NAME, X, 1A, 1B, 2A, 2B
1, abc, 123, 456, 789, 000, 000
2, lmn, 123, 456, 789, MISSING, MISSING
3, pqr, 123, 456, 789, 000, 000
9, opq, 123, MISSING, MISSING, 000, 000
eu useiessepara referência.
Eu tentei usar o seguinte:
join -t , -a1 -a2 -1 1 -2 1 -o 0 -o 1.2 -o 1.3 -o 1.4 -o 1.5 -o 2.4 -o 2.5 -e "MISSING" 1.txt 2.txt
O que produz:
1, abc, 123, 456, 789, 000, 000
2, lmn, 123, 456, 789,MISSING,MISSING
3, pqr, 123, 456, 789, 000, 000
9,MISSING,MISSING,MISSING,MISSING, 000, 000
Qualquer ajuda?
Responder1
Eu não acho que você possa fazer isso join
sozinho. Você poderia fazer:
join -t, -a1 -a2 -o0,1.2,1.3,1.4,1.5,2.2,2.3,2.4,2.5 -e MISSING 1.txt 2.txt |
perl -F, -lape '@F[1..2]=@F[5..6] if $F[1] eq "MISSING";
$_=join",",@F[0..4],@F[7..8]'
-p
: use um loop de leitura linha por linha como em sed/awk-a
,-F,
: como awk, divida as linhas em campos (no@F
array).-l
: funciona no conteúdo das linhas (funciona comoawk
onde a entrada é dividida emRS
($/
) (masRS
não incluída em$0
) eORS
($\
) é anexada antes da impressão).-e ...
: perl [e]xpressão a ser avaliada para cada linha.- Em seguida, parece quase como o inglês: os campos 1 a 2 são definidos como campos 5 a 6 se o campo 1 (o segundo campo, pois os índices começam em 0) for "MISSING". Em seguida, defina o conteúdo do registro atual ($_ é como $0 no awk) para os campos 0 a 4 e 7 a 8.
Na verdade, escrever o mesmo awk
não é mais complicado:
awk -F, -vOFS=, '$2 == "MISSING"{$2=$6;$3=$7}
{print $1,$2,$3,$4,$5,$8,$9}'
Responder2
usando apenas awk:
awk -F, -v OFS=, '
BEGIN {m = " MISSING"}
# process file1
NR == FNR {lines[$1] = $0; next}
# process file2
{
added[$1] = $4 OFS $5
if (!($1 in lines)) {
$4 = m
$5 = m
lines[$1] = $0
}
}
# print the combined output
END {
for (id in lines) {
if (!(id in added))
added[id] = m OFS m
print lines[id], added[id]
}
}
' 1.txt 2.txt | sort -n
1, abc, 123, 456, 789, 000, 000
2, lmn, 123, 456, 789, MISSING, MISSING
3, pqr, 123, 456, 789, 000, 000
9, opq, 123, MISSING, MISSING, 000, 000
Responder3
Parece que você deseja ingressar nos três primeiros campos. Você deve então alterar os dois primeiros delimitadores, join
no novo 1º campo e depois restaurar os delimitadores:
join -t, -j1 -a1 -a2 -o 0 1.2 1.3 2.2 2.3 -e " MISSING" \
<(sed 's/, /\x02/;s/, /\x02/' 1.txt) <(sed 's/, /\x02/;s/, /\x02/' 2.txt) \
| sed 's/\x02/, /g'
retorna
1, abc, 123, 456, 789, 000, 000
2, lmn, 123, 456, 789, MISSING, MISSING
3, pqr, 123, 456, 789, 000, 000
9, opq, 123, MISSING, MISSING, 000, 000