Присоединить: два файла, но добавить только два последних столбца

Присоединить: два файла, но добавить только два последних столбца

Учитывая файлы:

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

Связанный контент