Попробуйте:
awk 'FNR==NR{seen[$1]=$2; next} seen[$NF]{print $0, seen[$NF]}' file2 file1
С помощью ключа столбца $1 сохраните соответствующее значение столбца $2 в связанный массив с именем , видимый , когда awk читает только из файла2 , гдеNR==FNR
(всегда верно для первого входного файла, когда есть несколько входных файлов для чтения ), NR
будет установлено в 1 для первой записи/строки, прочитанной awk и увеличивается до тех пор, пока не будут прочитаны все записи/строки, если они одиночные входной файл или несколько файлов; FNR
установит значение 1 для первой записи/строки, считанной с помощью awk , и будет увеличиваться до тех пор, пока все записи/строки не будут прочитаны в текущем входном файле, и не будет сброшено обратно на 1 для следующего файла.
Следующий блок, если значение последнего столбца совпадает с тем же значением ключа в видимом массиве, затем напечатать всю строку из файла1 и значение того же ключа в массиве.
Я не уверен в цели вашей конструкции sed, но могу сказать вам о вашей ошибке в ней.
В вашем регулярном выражении вы пытаетесь сопоставить первые три комбинации цифр -с (.*),(.*),(.*)
. Поскольку регулярное выражение в sed «жадное», первое (.*)
уже будет соответствовать трем комбинациям, поскольку буквы, цифры и запятые соответствуют .
. Чтобы сопоставить отдельные комбинации, вам лучше сопоставлять без запятых (, например, ([^,] *), ведьма соответствует любому количеству символов без запятых. Тогда ваша команда будет выглядеть так:
echo -e "A1,B2,C2\nA2,B2,C2,D2,E2" | sed -E 's/^([^,]*),([^,]*),([^,]*)((,[^,]*)(,[^,]*)){0,1}$/[\1],\2,\3\5\6/'
Если это всегда входные данные из трех или пяти комбинаций, вы также можете «укоротить» регулярное выражение до
echo -e "A1,B2,C2\nA2,B2,C2,D2,E2" | sed -E 's/^([^,]*)(((,[^,]*){2}){1,2})$/[\1]\2/'
но на самом деле это зависит от вашего варианта использования. ^([^,]*)
соответствует комбинации первых букв -, ((,[^,]*){2})
соответствует следующим двум или четырем комбинациям с запятой перед ней (,B2,C2 или,B2,C2,D2,E2 в ваших примерах ввода ).
Все еще не уверен, чего пытается достичь OP, но чтобы получить не-жадное совпадение, вы можете использовать отрицательный класс символов, в данном случае [^,]
.
echo -e "A1,B2,C2\nA2,B2,C2,D2,E2" |
sed -E 's/([^,]+)((,[^,]+){2})((,[^,]+){0,2})/[\1]\2\4/'
[A1],B2,C2
[A2],B2,C2,D2,E2
echo -e "A1,B2,C2\nA2,B2,C2,D2,E2" |
sed -E 's/([^,]+)((,[^,]+){2})((,[^,]+){0,2})/[\1]\2\5/'
[A1],B2,C2
[A2],B2,C2,E2
Хотя ловить каждую спичку отдельно для приукрашивания — это другое дело...
Если бы OP соизволил привести более полный пример… возможно, мы все снова пойдем по кругу! Упражнение полезно для нас;)
$ echo -e "A1,B2,C2\nA2,B2,C2,D2,E2" | sed -e 's/[^,]*/[&]/' -e 's/[^,]*/(&)/2' -e 's/[^,]*/{&}/3'
[A1],(B2),{C2}
[A2],(B2),{C2},D2,E2
Вместо того, чтобы пытаться сделать все это за одну замену, вы можете использовать тот факт, что вы можете выбрать, с каким из совпадений работать, используя числовой флаг в конце (здесь /2
и /3
для 2-го и 3-го совпадения ).
Команда sed
, использованная выше, для ясности:
sed -e 's/[^,]*/[&]/' \
-e 's/[^,]*/(&)/2' \
-e 's/[^,]*/{&}/3'