Итак, задача: есть _data.txt_ с данными и _filter.txt_ со списком фильтрации.
Строки
data.txt обрабатываются, если есть совпадение в filter.txt. Это классическая задача фильтрации (например, обработка белых и чёрных списков). ㅤ
И да, я знаю про программы comm и join, с помощью которых можно решать подобные вещи, но мне нравится awk, потому что делает это гибче благодаря наличию языка программирования и не требует предсортировки.
👍 Итак, сама конструкция:
awk 'NR == FNR { filter[$0] = 1; next } $0 in filter { print $0, "in filter" }' filter.txt data.txtОбратите внимание: здесь два блока обработки строк, каждый со своим условием
1.
NR == FNR { filter[$0] = 1; next }2.
$0 in filter { print $0, "in filter" }Обычно выполняются оба блока: сначала первый, потом второй, но здесь это не так. Первый блок только считывает данные
filter.txt в массив filter. Второй обрабатывает только те строки, которые есть в массиве.
NR — встроенная переменная, номер записи ДЛЯ ВСЕХ файлов. FNR — аналогична предыдущей, но начинается с 1 для каждого нового файла. filter[$0] = 1 — сохраняем всю строку первого файла как ключ массива. next — сразу переходит к обработке следующей строки. Таким образом, связка условия
NR == FNR и next будет работать только для первого файла (filter.txt).Для второго файла условие
NR == FNR уже не соблюдается, поэтому первый блок не выполняется, а второй выполняется, если строка данных присутствует в массиве filter. Ну и пример из реальной жизни —
filter.txt: RU
BY
data.txt RU 127.0.0.1
BY 127.0.0.2
US 127.0.0.3
KZ 127.0.0.4
awk 'NR == FNR { filter[$1] = 1; next } $1 in filter { print $2, "in filter" }' filter.txt data.txt
127.0.0.1 in filter
127.0.0.2 in filterОбратите внимание: на выходе только нужные строки и только нужный столбец. Как же это круто!
Маленькое ограничение: содержимое
filter.txt, загруженное в массив filter, должно помещаться в оперативную память. Иначе система может начать активно использовать swap, а процесс — завершиться из-за нехватки памяти. man awk
man comm
man join
Всем работы без багов.
© Tagd Tagd
—