С датой 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
Да, вы можете сделать это с помощью 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)
Правильным инструментом для этого действительно является 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
.
Я добавил 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