Учитывая файлы:
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
ВЫХОД.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
Я использовалэтотдля справки.
Я попробовал использовать следующее:
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
Что производит:
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
Любая помощь?
решение1
Я не думаю, что ты сможешь сделать это в join
одиночку. Ты мог бы сделать:
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
: использовать цикл построчного чтения, как в sed/awk-a
,-F,
: подобно awk, разбивает строки на поля (в@F
массив).-l
: работает с содержимым строк (работает так же, как иawk
в случае, когда ввод разделяется наRS
($/
) (ноRS
не включается в$0
) иORS
($\
) добавляется перед печатью).-e ...
: выражение perl [e]xpression для оценки для каждой строки.- Тогда это читается почти как английский: поля 1-2 устанавливаются в поля 5-6, если поле 1 (второе поле, поскольку индексы начинаются с 0) "MISSING". Затем установите содержимое текущей записи ($_ это как $0 в awk) в поля 0-4 и 7-8.
На самом деле, написать то же самое на awk
не сложнее:
awk -F, -vOFS=, '$2 == "MISSING"{$2=$6;$3=$7}
{print $1,$2,$3,$4,$5,$8,$9}'
решение2
используя только 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
решение3
Похоже, вы хотите объединить первые три поля. Затем вам следует изменить первые два разделителя join
на новом 1-м поле, а затем восстановить разделители:
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'
возвращается
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