Date не принимает этот формат ввода, попробуйте поставить год первым, например, stream Редактирование ввода:
cut -f 9 file | sed 's/\(..\)-\(..\)-\(....\)/\3-\1-\2/' > tmpfile
Проверка вручную:
$ date --date '09-13-1970' "+%B %d, %Y"
date: invalid date ‘09-13-1970’
$ date --date '09/13/1970' "+%B %d, %Y"
September 13, 1970
$ date --date '1970/09/13' "+%B %d, %Y"
September 13, 1970
$ date --date '1970-09-13' "+%B %d, %Y"
September 13, 1970
Создайте следующие файлы:
merge21
:
BEGIN { FS = "\t" OFS = "\t" } NR==FNR { # file2 key = $2 "," $3 present[key] = 1 minor8[key] = $1 next } { # file1 key = $1 "," $3 if (present[key]) print $1, $2, $3, $4, minor8[key] else print $1, $2, $3, $4, "-" }
merge312
:
BEGIN { FS = "\t" OFS = "\t" } NR==FNR { # file3 key = $1 "," $2 present[key] = 1 minor9[key] = $3 next } { # file1 + file2 key = $1 "," $3 if (present[key]) print $1, $2, $3, $4, $5, minor9[key] else print $1, $2, $3, $4, $5, "-" }
Они почти идентичны; Я выделил различия жирным шрифтом. Теперь введите команду
awk -f merge21 file2 file1 | awk -f merge312 file3 -
. Предполагается, что ни одно из ваших ключевых полей не содержит запятых
и ни в одном из ваших данных нет дефисов,
, но на самом деле это зависит только от них некоторые строки
, которые не отображаются в данных.
Было бы тривиально расширить это для поддержки большего количества столбцов;
Я надеюсь, что это очевидно.
Этот может быть расширен, чтобы делать все за один прогон awk
,
но это было бы немного сложнее, и (IMNSHO) не стоит усилие.
Это создает так называемое «левое внешнее соединение» данных в ваших файлах; см. Различие между INNER и OUTER соединениями в Stack Overflow для некоторых определений .(«Левое внешнее соединение» определяется в принятом ответе на этот вопрос как (перефразировано) «все строки в первой таблице плюс любые общие строки в другой таблице (ах)». )
Ваш вывод будет
MAIN1 minor1 MAIN2 minor3 minor8 minor9
1 bla1 a blabla1 yes6 sure3
1 bla2 b blabla2 yes7 sure4
1 bla3 c blabla3 yes8 sure5
2 bla4 a blabla4 yes9 sure6
2 bla5 d blabla5 - sure7
3 bla6 e blabla6 yes2 sure8
4 bla7 f blabla7 yes3 sure9
5 bla8 a blabla8 yes4 -
5 bla9 g blabla9 yes5 sure2
и, очевидно, вы можете удалить символы -
с помощью sed
.
(И, конечно, если ваши реальные данные действительно содержат дефисы,
выберите какой-нибудь неиспользуемый символ или строку в качестве заполнителя для отсутствующих данных.)
FS
и OFS
являются разделителем входного поля
и разделителем выходного поля соответственно.
(Очевидно IFS
бессмысленен в awk
; это была ошибка с моей стороны.)
Вам, вероятно, действительно не нужен FS = "\ t"
-
awk
по умолчанию распознает табуляции как разделители полей при вводе.
(Он позволяет вам иметь поля, содержащие пробелы,
, но, похоже, вас это не интересует.)
OFS = "\ t"
является важным; из-за этого я могу сказать напечатать $ 1, $ 2, $ 3, $ 4
и получить поля ввода output с табуляцией между ними.
Если бы я не сказал OFS = "\ t"
, они были бы разделены пробелами,
если я не сказал print $ 1 "\ t" $ 2 " \ t "$ 3" \ t "$ 4
,
, что утомительно и ухудшает удобочитаемость. Если вы задали дополнительные ограничения для MAIN1 и MAIN2 - например,
, они всегда состоят из одного символа каждый,
или MAIN1 всегда является числом, а MAIN2 всегда начинается с буквы - { {1}} Мне не нужна была бы запятая (,
) в ключе
.
Но в исходной версии вашего первого вопроса такого ограничения нет.
Рассмотрим следующие данные:
MAIN1 ($ 2) MAIN2 ($ 3) badkey = $ 2 $ 3 goodkey = $ 2 "," $ 3
2 34151 234151 2,34151
23 4151 234151 23,4151
Если мы не добавим в ключ
какой-либо символ-разделитель, который иначе не появится в ключевых полях (MAIN1 и MAIN2),
мы можем получить одинаковое значение ключа
для разных строк.
awk
, что делать. NR == FNR {# file3 key = $ 1 "," $ 2 present [key] = 1 { {1}} minor9 [key] = $ 3 next }Рассмотрим седьмую с последней строки
file3
,
который содержит 1 a sure3
.
Очевидно, у нас есть $ 1
= 1
, $ 2
= a
и $ 3
= sure3
, поэтому ключ
= 1, a
.
present [key] = 1
означает, что я устанавливаю present ["1, a"]
на 1
как флаг {{1} }, чтобы указать, что file3
имеет a 1, строку
;
т. е. что существует значение minor9
для ключ
= 1, a
.
Поскольку нет 5, строка
в file3
, present ["5, a"]
не устанавливается, {{ 1}} и поэтому часть кода " file1 + file2
"
знает, что нет minor9
для ключа
= 5, a
,
, и вместо этого он должен вывести -
.
Имя присутствует
- это просто произвольный выбор с моей стороны;
оно означает, что строка 1,
присутствует в file3
(а в 5, в строке
нет).
Обычно используется 1
для представления «ИСТИНА». Вы можете заменить print $ 1, $ 2, $ 3, $ 4
на for (n = 1; n <= 4; n ++) printf "% s \ t", $ n
.
Вы должны завершить строку, используя простой print
(в отличие от printf
) для последнего поля, либо выполнив printf "\ п"
.
Вы можете упростить еще больше, выполнив что-то вроде
for (n = 1; n <= 4; n ++) printf "% s \ t", $ n if (present [key ]) print minor8 [key] else print "-"
Прочтите awk (1) , спецификацию POSIX для awk
, {{ 1}} Руководство пользователя GNU Awk и дополнительную информацию см. В Awk.info .