У меня есть два файла: master.tbl
иsites.lst
Файл master.tbl
представляет собой список сайтов с их конфигурациями портов, именами портов, IP-адресами и т. д. Есть строки, содержащие описания сайтов, комментарии и т. д., но они не имеют значения. Строки, содержащие конфигурации сайтов, организованы следующим образом и разделены пробелами.:
{server} {SITE NAME} {port name} {configuration flags}
Имена портов состоят из имени сайта строчными буквами, тире, буквы «P» и номера порта.
Пример:
server01 HAWAII23-USR hawaii23-P1 blah-configuration-blah-arguments
server01 HAWAII23-ADM hawaii23-P2 blah-configuration-blah-arguments
server01 HAWAII23-ADM hawaii23-P3 blah-configuration-blah-arguments
server01 HAWAII23-USR hawaii23-P4 blah-configuration-blah-arguments
sites.lst
список сайтов, master.tbl
на которых мне нужно выполнить поиск в файле.
Мне нужно закомментировать (вставить a #
в начале строки) и извлечь имя сервера и имя порта (в файл с именем stoplist.lst
) каждой строки, которая соответствует ВСЕМ следующим критериям:
- содержит любое имя сайта, перечисленное в
sites.lst
- содержит "-АДМ"
- имеет номер порта больше «2» (пример:
hawaii23-P3
)
В приведенном выше примере master.tbl
файл будет выглядеть так:
server01 HAWAII23-USR hawaii23-P1 blah-configuration-blah-arguments
server01 HAWAII23-ADM hawaii23-P2 blah-configuration-blah-arguments
#server01 HAWAII23-ADM hawaii23-P3 blah-configuration-blah-arguments
server01 HAWAII23-USR hawaii23-P4 blah-configuration-blah-arguments
...и stoplist.lst
будет содержать (предполагая, HAWAII23
что находится в sites.lst
):
server01 hawaii23-P3
master.lst
почти 300 000 строк, поэтому делать это вручную было бы... плохо.
решение1
Вот awk
решение:
awk 'NR==FNR{z[$0"-ADM"]++;next}
{p=$3;sub(/.*-P/, "", p); if ($2 in z && p > 2)
{print $1,$3 > "stoplist.lst"; $0="#"$0}}1' sites.lst master.tbl
Сначала он считывает sites.lst
и устанавливает $0"-ADM"
(то есть имя сайта + строку -ADM
) как индекс массива z
. Затем он обрабатывает master.tbl
извлечение значения после -P
в 3-м поле как p
и, если условия выполнены (2-е поле находится внутри z
и p
больше 2), он печатает 1-е и 3-е поля stoplist.lst
и комментирует строку.
Обратите внимание, что он не редактирует файл на месте, но вы всегда можете перенаправить на другой файл и перезаписать исходный, если все в порядке (хотя с недавним gnu awk
у вас есть возможность -i inplace
).