Удалять строки из одного файла, если они содержат регулярное выражение содержимого в другом файле

У меня большой файл (150K + строк), содержащий записи DNS, я буду называть это FileA. У меня есть файл меньшего размера, содержащий определенные имена, FileB. Я хочу удалить все строки в FileA, которые заканчиваются тем, что находится в FileB. Но я не хочу удалять строку, если имя появляется в начале записи.

Я знаю, как использовать grep -v name$ чтобы вручную удалить имена, которые появляются в конце записи, но мне нужен цикл, чтобы пройти через весь FileB. Пока мои попытки потерпели неудачу.

Вот пример, на который я надеюсь проиллюстрировать, что мне нужно:

 FileA: hosta IN A 10.20.30.40 hostb IN A 20.30.40.50 myurl IN CNAME hostb yours IN CNAME hostb 

Если FileB содержит hostb, удаляются только две последние строки; первые две строки остаются как есть.

  • Неожиданный EOF при поиске соответствия `''
  • Regex работает в оболочке, но не через скрипт Perl
  • что означает «^ $ 1» в сценарии оболочки?
  • Переместить файл на основе его содержимого
  • Ошибка Exec vs source на ==
  • Из машины Ubuntu я хочу отправить файл другому пользователю по электронной почте автоматически без какой-либо ручной работы
  • Извлечь поля строки в переменные оболочки
  • Как проверить, установлен ли vim?
  • 3 Solutions collect form web for “Удалять строки из одного файла, если они содержат регулярное выражение содержимого в другом файле”

    Вы можете использовать флаг -f для grep для всех строк в FileB:

     grep -v -f FileB FileA 

    Это почти то, что вы хотите. Но это также удаляет строки, в которых шаблоны из FileB не заканчиваются, и вы явно заявили, что они должны соответствовать только тогда, когда они находятся в конце. Поэтому нам нужно соответствующим образом изменить FileB . Мы можем использовать sed , чтобы добавить regex для конца строки, которое является знаком $ :

     sed 's/$/$/' FileB 

    Похоже, что это ничего не заменяет, но на самом деле добавляет $ на каждом конце строки.

    Теперь мы можем использовать замену процессов, чтобы собрать все это вместе:

     grep -v -f <(sed 's/$/$/' FileB) FileA 

    Чтобы перебрать весь FileB, вы можете использовать такой подход, как:

     for i in `cat FileB` do <do your work> done 

    Но, возможно, будет лучше фильтровать также CNAME

    С sed вы можете сделать это следующим образом:

     sed -n '/^[^ ]*$/{H;d;};G;/ \(.*\)\n.*\n\1/d;P' fileB fileA 

    Это: Первый файл процесса. Если строки не содержат пробелов, они должны быть именами хостов в файлеB, и мы добавляем их в пространство удержания и продолжаем ( {H;d;} )

    Все остальные строки должны быть fileA. Добавив пространство удержания в список имен узлов ( G ), все строки с последним словом строки, которые повторяются в списке имен узлов, могут быть удалены. Остальные строки печатаются без конечного списка ( P ). Опция -n отменяет вывод по умолчанию.

    Изменить: на самом деле нужно делать

     sed -n '/^[^ ]*$/{H;d;};G;/ \(.*\)\n.*\n\1\n/d;/ \(.*\)\n.*\n\1$/d;P' fileB fileA 

    чтобы избежать особых случаев.

    Interesting Posts

    whats является командой для конкретных конкретных компонентов компонента?

    Настроить сенсорный экран на Debian?

    Пакетное переименование файлов с неизвестными именами и неизвестными расширениями

    Запустите контейнер Docker и откройте веб-браузер на хосте

    vi commandline, goto строка и столбец

    найти символ и присоединиться к этой строке со следующей

    Раскрасить имена файлов на основе состояния для git diff -name-status

    Как отключить строки под текстом в редакторе Kate?

    Способы выполнения / etc / network / interfaces?

    Почему «mkpasswd -m sha-512» производит разные результаты каждый раз, когда он называется?

    как сравнить два xml-файла с одинаковыми данными в разных строках?

    Как создать относительную символическую ссылку с учетом относительного пути?

    Git всегда выводит ошибку для двоичного файла

    Использование sed для замены строки со многими специальными символами?

    Как получить список затронутых файлов между двумя точками времени?

    Linux и Unix - лучшая ОС в мире.