Как заменить необязательный суффикс в sed

Попробуйте:

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 и значение того же ключа в массиве.

1
04.05.2020, 23:33
3 ответа

Я не уверен в цели вашей конструкции 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 в ваших примерах ввода ).

1
28.04.2021, 23:16

Все еще не уверен, чего пытается достичь 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 соизволил привести более полный пример… возможно, мы все снова пойдем по кругу! Упражнение полезно для нас;)

1
28.04.2021, 23:16
$ 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'
1
28.04.2021, 23:16

Теги

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