Я уверен, что однажды нашел команду unix, которая могла бы печатать общие строки из двух или более файлов, кто-нибудь знает ее название? Это было намного проще, чем diff
.
unix
shell
command-line
слишком много PHP
источник
источник
comm
требует отсортированных входных файлов. Если вы хотите просто построчно, это здорово. Но если вы хотите то, что я бы назвал «антидифф»,comm
не делайте эту работу.pr-123-xy-45
и file2 содержитec11_orop_pr-123-xy-45.gz
. Мне нужен file3, содержащийec11_orop_pr-123-xy-45.gz
Ответы:
Команда, которую вы ищете, это
comm
. например:-Вот:
-1 : подавить столбец 1 (строки уникальны для 1.sorted.txt)
-2 : подавить столбец 2 (строки уникальны для 2.sorted.txt)
источник
grep
делает некоторые странные вещи, которые вы, возможно, не ожидаете. В частности, все в1.txt
будет интерпретироваться как регулярное выражение, а не простая строка. Кроме того, любая пустая строка в1.txt
будет соответствовать всем строкам в2.txt
. Такgrep
будет работать только в очень специфических ситуациях. Вы по крайней мере хотели бы использоватьfgrep
(илиgrep -f
), но пустая строка, вероятно, нанесет ущерб этому процессу.grep -F -x -f file1 file2
.comm
команды в 3 отдельных файла? Ответ был слишком велик, чтобы здесь было удобно.Чтобы легко применить команду comm к несортированным файлам, используйте процесс подстановки Bash :
Таким образом, файлы abc и def имеют одну общую строку, одну с «132». Использование comm для несортированных файлов:
Последняя строка не выдала, общая линия не была обнаружена.
Теперь используйте comm для отсортированных файлов, сортируя файлы с подстановкой процесса:
Теперь мы получили линию 132!
источник
sort abc > abc.sorted
,sort dev > def.sorted
а потомcomm -12 abc.sorted def.sorted
?Чтобы дополнить Perl-однострочник, вот его
awk
эквивалент:Это будет считывать все строки из
file1
массиваarr[]
, а затем проверять каждую строку,file2
если она уже существует в массиве (то естьfile1
). Найденные строки будут напечатаны в том порядке, в котором они отображаютсяfile2
. Обратите внимание, что для сравненияin arr
используется вся строка отfile2
индекса до массива, поэтому он будет сообщать только о точных совпадениях во всех строках.источник
perl
, потому что).Может ты имеешь ввиду
comm
?Секрет в поиске этой информации - информационные страницы. Для программ GNU они намного более подробны, чем их man-страницы. Попробуйте,
info coreutils
и он перечислит вам все маленькие полезные утилиты.источник
Пока
дает вам различия двух файлов (что в 2.txt, а не в 1.txt), вы можете легко сделать
собрать все общие линии, которые должны обеспечить простое решение вашей проблемы. Если у вас есть отсортированные файлы, вы должны принять,
comm
тем не менее. С уважением!источник
grep
делает некоторые странные вещи, которые вы не могли бы ожидать. В частности, все в1.txt
будет интерпретироваться как регулярное выражение, а не простая строка. Кроме того, любая пустая строка в1.txt
будет соответствовать всем строкам в2.txt
. Так что это будет работать только в очень специфических ситуациях.grep
нотации POSIX , которые поддерживаются вgrep
большинстве современных вариантов Unix. Добавьте-F
(или используйтеfgrep
) для подавления регулярных выражений. Добавьте-x
(для точного), чтобы соответствовать только целые строки.comm
отсортированные файлы?comm
может работать с произвольно большими файлами до тех пор, пока они сортируются, потому что для этого требуется всего лишь три строки в памяти (я предполагаю, что GNUcomm
даже знает, что нужно сохранить только префикс, если строки действительно длинные).grep
Решение должно сохранять все поисковые выражения в памяти.Если два файла еще не отсортированы, вы можете использовать:
и это будет работать, избегая сообщения об ошибке
comm: file 2 is not in sorted order
при выполненииcomm -12 a.txt b.txt
.источник
<(command)
не переносится в оболочку POSIX, хотя он работает в Bash и некоторых других.источник
comm
команда, поскольку она ищет каждую строкуfile1
в,file2
гдеcomm
будет сравниваться, только если строкаn
вfile1
равна строкеn
вfile2
.comm
не просто сравнивает строку N в файле1 со строкой N в файле2. Он может прекрасно управлять серией строк, вставленных в любой файл (что, конечно, эквивалентно удалению серии строк из другого файла). Это просто требует, чтобы входы были в отсортированном порядке.comm
ответы, если кто-то хочет сохранить порядок. Лучше, чемawk
отвечать, если никто не хочет дубликатов.источник
На ограниченной версии Linux (например, QNAP (nas), над которой я работал):
grep -f file1 file2
может вызвать некоторые проблемы, как сказал @ChristopherSchultz, и использованиеgrep -F -f file1 file2
было очень медленным (более 5 минут - не завершено - более 2-3 секунд с методом ниже для файлов размером более 20 МБ)Итак, вот что я сделал:
Если
files.same.sorted
он будет в том же порядке, что и исходные, то добавьте эту строку для того же порядка, что и файл1:или для того же порядка, что и file2:
источник
Просто для справки, если кто-то все еще ищет, как это сделать для нескольких файлов, см. Связанный ответ « Поиск совпадающих строк во многих файлах».
Объединяя эти два ответа ( ans1 и ans2 ), я думаю, что вы можете получить нужный результат без сортировки файлов:
Просто сохраните его, дайте ему права на выполнение (
chmod +x compareFiles.sh
) и запустите его. Он примет все файлы, присутствующие в текущем рабочем каталоге, и выполнит сравнение «все против всех», оставив в файле «Match_Lines» результат.Что нужно улучшить:
источник
Это должно сделать это.
источник
rm -f file3.txt
если вы собираетесь удалить файл; это не сообщит ни о какой ошибке, если файл не существует. OTOH, это не было бы необходимо, если бы ваш скрипт просто отображал стандартный вывод, позволяя пользователю сценария выбирать, куда выводить данные. В конечном счете, вы, вероятно, захотите использовать$1
и$2
(аргументы командной строки) вместо фиксированных имен файлов (file1.out
иfile2.out
). Это оставляет алгоритм: он будет медленным. Это будет читатьfile2.out
один раз для каждой строки вfile1.out
. Это будет медленно, если файлы большие (скажем, несколько килобайт).grep -F
который читает один файл в память, а затем делает один проход над другим, избегает многократного зацикливания обоих входных файлов.