С AWK вы могли бы сделать что-то вроде
awk -F \| 'BEGIN { OFS = FS } NR == FNR { val[$2] = $1; next } $1 in val { $(NF + 1) = val[$1]; print }' file2 file1
NF
является количество полей в записи (строка по умолчанию), поэтому $NF
последнее поле, и $(NF + 1)
это поле после этого. Назначив сохраненное значение из прохода над file2
, к нему будет добавлено новое поле перед его печатью.
Следует отметить: это ведет себя как внутреннее соединение, то есть печатаются только записи, ключ которых отображается в обоих файлах. Чтобы сделать это право присоединиться, вы можете использовать
awk -F \| 'BEGIN { OFS = FS } NR == FNR { val[$2] = $1; next } { $(NF + 1) = val[$1]; print }' file2 file1
То есть, вы можете отказаться от условия $1 in val
на действии конкатенирующего и-печати. Если $1
не находится в val
, val[$1]
пуст, и перед печатью будет добавлено пустое поле.
Но это, вероятно, лучше использовать join
:
join -1 1 -2 2 -t \| file1 file2
Если вы не хотите, ключевое поле, чтобы быть частью производства, трубы на выходе любой из этих команд через cut -d \| -f 2-
, чтобы избавиться от него , т.е.
join -1 1 -2 2 -t \| file1 file2 | cut -d \| -f 2-
Вы можете избежать трубопровода, чтобы вырезать, добавить опцию Объединить : '-o 1.2.1.3,1.4,2.2' –
Мне нравится использование' $ (NF + 1) '. Вы можете сделать это более awk-ish, перемещая выражение if вне фигурных скобок: '$ 1 в val {$ (NF + 1) = val [$ 1]; print} ' –
@glennjackman О, это хороший момент. Однако я буду придерживаться 'cut', чтобы сбрить ключевое поле с выхода; опцион '-o' может решить проблему, как указано, и имеет свои преимущества, но я чувствую, что преимущество подхода' cut', которое он работает с произвольным количеством столбцов, перевешивает их здесь. Если бы производительность была заявлена как проблема, все могло бы быть иначе. – Wintermute