объединение массивов в матрицу -добавление разделителей между ячейками

С датой BSD, поставляемой в OSX, вы можете

timestring="2020-01-17T06:41:48.456Z"
/bin/date -jf "%Y-%m-%dT%H:%M:%S" "${timestring%.???Z}" "+%s${timestring: -4:3}"
1579261308456
2
13.11.2020, 18:09
3 ответа

Да, вы можете сделать это с помощью Awk, но Join был создан для этой задачи:

join -a1 -a2 file1 file2

Вывод заданных выборок:

001 A
002 B D
003 C D
004 D
005 E
006 F

Обратите внимание, что файлы необходимо отсортировать перед запуском join. Если ваша оболочка поддерживает это, вы можете сделать это за один шаг, используя подстановку процесса:

join -a1 -a2 <(sort file1) <(sort file2)
4
28.04.2021, 23:05

Правильным инструментом для этого действительно является join, , как показал вам Квазимодо , но вы также можете использовать ту же команду awk с очень незначительной модификацией:

$  awk '{ z[$1]=z[$1]" "$2 } END { for (i in z) print i, z[i] }' file1  file2
002  B D
003  C D
004  D
005  E
006  F
001  A

Я изменил только z[$1]=z[$1]$2 на z[$1]=z[$1]" "$2.

3
28.04.2021, 23:05

Я добавил 004 Dв файл2, чтобы у нас был неочевидный случай -для тестирования. Учитывая, что либо это:

$ sort -k1,1 -s file1 file2 |
awk '
    $1 != prev { if (NR>1) print ""; printf "%s", $1; prev=$1 }
    { printf " %s", $2 }
    END { print "" }
'
001 A
002 B D
003 C D
004 D D
005 E
006 F

или это:

$ sort -k1,1 -s file1 file2 |
awk '
    $1 != prev{if (NR>1) print ""; printf "%s", $1; prev=$1; delete seen }
    !seen[$2]++ { printf " %s", $2 }
    END { print "" }
'
001 A
002 B D
003 C D
004 D
005 E
006 F

в зависимости от того, как вы хотите обрабатывать повторяющиеся значения для одного и того же ключа. Просто перечислите столько файлов, сколько хотите, в строке sort. Вышеприведенное предполагает сортировку GNU для -sдля сохранения порядка ввода для тех же ключей, если у вас этого нет и он действительно нужен, есть простые альтернативы. Вы также можете тривиально настроить это так, чтобы ABC и т. д. всегда располагались в алфавитном порядке в каждой выходной строке, а не в том порядке, в котором они встречаются в каждом входном файле, если хотите, например.:

$ head file*
==> file1 <==
001    A
002    E
003    F
004    D

==> file2 <==
002    D
003    D
004    D
005    E
006    F

==> file3 <==
001    A
002    E
003    C
004    D

$ sort -s file* | awk '$1 != prev{if (NR>1) print ""; prev=$1; delete seen; printf "%s", $1} !seen[$2]++{printf " %s", $2} END{print ""}'
001 A
002 D E
003 C D F
004 D
005 E
006 F
1
28.04.2021, 23:05

Теги

Похожие вопросы