Сравните два списка URL-адресов и напечатайте вновь добавленные URL-адреса в новый файл.

8

Первоначально я создаю два файла, которые содержат списки URL-адресов - я буду ссылаться на них как oldи new. Я хотел бы сравнить два файла, и если в newфайле есть URL-адреса, которых нет в oldфайле, я бы хотел, чтобы они отображались в extra_urlsфайле.

Теперь я прочитал кое-что об использовании diffкоманды, но из того, что я могу сказать, это также анализирует порядок информации. Я не хочу, чтобы заказ оказал какое-либо влияние на результат. Я просто хочу, чтобы дополнительные URL были newнапечатаны в extra_urlsфайле, независимо от того, в каком порядке они размещены в любом из двух других файлов.

Как я могу это сделать?

neilH
источник

Ответы:

14

Команду можно использовать commдля сравнения двух файлов и выборочного отображения строк, уникальных для одного или другого, или общих строк. Это требует сортировки входных данных, но вы можете отсортировать их на лету, используя подстановку процесса.

comm -13 <(sort old.txt) <(sort new.txt)

Если вы используете версию bash, которая не поддерживает подстановку процессов, ее можно эмулировать, используя именованные каналы. Пример показан в Википедии .

Barmar
источник
Краткий, но эффективный - именно то, что нужно, отличный кусок кода для того, что мне нужно.
neilH
Хм, но если вход отсортирован, то diffбудет делать то же самое, верно?
Половина
diffпокажет все отличия. commпозволяет выбрать, хотите ли вы видеть строки из файла 1, файла 2 или те, которые у них общие.
Бармар
Привет, Бармар, не уверен, что ты это проверишь, но только что, я переместил этот скрипт на мой Synology Nas, чтобы запустить его оттуда. С момента запуска моего скрипта из Synology я теперь получаю синтаксическую ошибку: строка 60: синтаксическая ошибка: неожиданно "("
neilH
Какая версия bashработает? Это может не поддерживать процесс замены.
Бармар
6

Я бы просто использовал grep:

grep -vFf old new > extra_urls

объяснение

  • -f: говорит, grepчтобы прочитать его шаблоны поиска из файла. В этом случае old.
  • -v : сообщает grep, что нужно инвертировать совпадение, чтобы печатать только несоответствующие строки.
  • -F: говорит grep интерпретировать свои шаблоны поиска как строки, а не как регулярные выражения. Таким образом, .URL будет совпадать буквально.

В совокупности они позволяют grepпечатать любые строки new, которых не было в old. Порядок URL-адресов в файле не имеет значения.

Тердон
источник
Привет, Тердон, спасибо за ваш вклад. Я только что проверил это, и он выдал пустой «дополнительный URL-адрес» _файл, несмотря на наличие новых URL-адресов в «новом» файле.
neilH
@ bms9nmh хм, это странно. Пожалуйста, измените ваш вопрос, чтобы привести пример ваших входных файлов. Вы также можете зайти в чат на сайте, где мы можем обсудить это дальше.
Terdon
2
Вы хотите, чтобы добавить -Fдля простых текстовых шаблонов
Гленн Джекман
1

Так как порядок важен для вас, используйте awk

awk '
    NR == FNR {old[$1]=1; next}
    !($1 in old)
' old new > extra
Гленн Джекман
источник
1
Привет Глен, просто чтобы уточнить, порядок не важен. Порядок URL-адреса не является проблемой, просто разница между двумя файлами, то есть дополнительными URL-адресами. Я не хочу разницы, чтобы как-то повлиять на результат.
neilH
@ bms9nmh: вы можете просто изменить > extraна | sort > extra. или | sort -u > extraесли вы хотите, чтобы новый URL-адрес появлялся на выходе только один раз, независимо от того, сколько раз он был на входе. Порядок ввода может повлиять на порядок вывода, если вы не проделаете дополнительную работу, чтобы предотвратить это.
Стив Джессоп
@steve, meh, commявляется лучшим ответом на этот вопрос, хотя grep -Fvfтоже хорош
Гленн Джекман
0

У меня есть приложение под названием Meld. Он позволяет просматривать два (или три) файла рядом друг с другом, показывает различия и позволяет выборочно копировать один в другой или удалять символы.

Meld может быть установлен из терминала с

sudo apt-get install meld 
krazykyngekorny
источник