Сегодня меня попросили сравнить заголовки небольших абзацев в двух больших текстовых файлах. Все заголовки начинались со звёздочки, поэтому проблем не возникло. Но совсем без проблем не интересно и больше от скуки, чем для реального пользования, захотелось найти способ для вытаскивания заголовков из любого текста. К сожалению 100% рабочий способ не был найден, однако в конце статьи будет интересное решение по превращению двойных и более пустых строк в одну пустую строку.
Для начала простейший вариант, когда надо просто сравнить 2 текстовых файла.
Для этого есть команда diff. Синтаксис следующий:
diff первый_файл второй_файл
Гораздо удобнее перенаправить вывод в файл с расширением diff
diff первый_файл второй_файл > profit.diff
Если такой файл открыть в текстовом редакторе, то будет подсвечен синтаксис и процесс анализа облегчится.
Программа сравнивает строки и если в одном из файлов присутствует строка, которой нет в другом, то ставится знак «>» или «
Чтобы получить вывод строк, которые начинаются с одного символа (в данном случае это *), то лучше всего воспользоваться командой grep. Например, если нужно отправить в файл 1.txt все строки, которые начинаются с «*» в файле file.txt, то для этого следует выполнить
grep "^*" "file.txt" > 1.txt
Что касается вытаскивания заголовков из текста любого формата, то тут ничего толкового не получилось.
Но не пропадать же коду, пусть лежит тут:
#!/bin/bash
n=$1
st=`sed -n ‘/^$/p’ $n| wc -l | awk ‘{print$1}’` #считаем кол-во пустых строк
sed -nr ‘/^.{100}/!p’ $n > /tmp/copy2$n #интересуют только строки с менее чем 100 символами (вряд ли заголовки будут длиннее)
sed -n «1p» /tmp/copy2$n > ‘Заголовки ‘$n # Выносим первую строку (уж она то будет заголовком)
#
tr ‘n’ ‘^’ /tmp/copy$n # Меняем все переносы на символ ^
#
#Меняем последовательность из ^^^(и т.д.) на двойные переносы (получается пустая строка)
#А одинарный ^ меняем на одинарный перенос (без пустой строки).
sed -i ‘s/^^^^^^^^^^^^^^^^^^/nn/g’ /tmp/copy$n
sed -i ‘s/^^^^^^^^^^^^^^^^^/nn/g’ /tmp/copy$n
sed -i ‘s/^^^^^^^^^^^^^^^^/nn/g’ /tmp/copy$n
sed -i ‘s/^^^^^^^^^^^^^^^/nn/g’ /tmp/copy$n
sed -i ‘s/^^^^^^^^^^^^^^/nn/g’ /tmp/copy$n
sed -i ‘s/^^^^^^^^^^^^^/nn/g’ /tmp/copy$n
sed -i ‘s/^^^^^^^^^^^^/nn/g’ /tmp/copy$n
sed -i ‘s/^^^^^^^^^^^/nn/g’ /tmp/copy$n
sed -i ‘s/^^^^^^^^^^/nn/g’ /tmp/copy$n
sed -i ‘s/^^^^^^^^^/nn/g’ /tmp/copy$n
sed -i ‘s/^^^^^^^^/nn/g’ /tmp/copy$n
sed -i ‘s/^^^^^^^/nn/g’ /tmp/copy$n
sed -i ‘s/^^^^^^/nn/g’ /tmp/copy$n
sed -i ‘s/^^^^^/nn/g’ /tmp/copy$n
sed -i ‘s/^^^^/nn/g’ /tmp/copy$n
sed -i ‘s/^^^/nn/g’ /tmp/copy$n
sed -i ‘s/^^/nn/g’ /tmp/copy$n
sed -i ‘s/^/n/g’ /tmp/copy$n
#
while [ $st -gt 0 ] #цикл на такое же кол-во раз, сколько и пустых срок.
do
st=$[$st-1]
sed -i ‘1,/^$/ d’ /tmp/copy$n #удаление всех строк до первой пустой (включая её саму)
sed -n «1p» /tmp/copy$n >> ‘Заголовки ‘$n #оставшуюся строку добавляем в файл
done
Кстати, этот код вполне справился со сравнением тех файлов, которые были мне присланы, однако с реальными книгами были проблемы.
), их сравнений, а также сравнений GUI-клиентов для них. Также были обсуждения плагинов к IDE для работы с git и mercurial. Но практически не было информации об инструментах визуального сравнения и разрешения конфликтов слияния.
Недавно я «перескочил» с mercurial (который до сих пор считаю более удобным и логичным) на git, потому что, подавляющее большинство проектов, которые мне интересны, используют git и хостятся на github. В связи с этим, встал вопрос о пересмотре арсенала инструментов, в частности вопрос выбора инструмента визуального сравнения и слияния (diff and merge). Дабы восполнить недостаток информации на хабре, я решил написать этот мини-обзор. Как говориться - по горячим следам.
Под катом Вы также найдете примеры настроек Git для использования с DiffMerge и WinMerge под Windows. Думаю многим сэкономит время.
Название | Особенности | Платформа |
KDiff3Git и WinMerge1) Добавим в директорию c:/Git/libexec/git-core/mergetools/файл winmerge следующего содержания: Diff_cmd () {
"c:/Program Files (x86)/WinMerge/WinMergeU.exe" \
"$LOCAL" "$REMOTE" >/dev/null 2>&1
}
merge_cmd () {
"c:/Program Files (x86)/WinMerge/WinMergeU.exe" \
"$PWD/$LOCAL" "$PWD/$REMOTE" "$PWD/$MERGED" >/dev/null 2>&1
status=$?
}
<<<<<<< HEAD
master str
=======
new str
>>>>>>> new
После этого откроется средство двухстороннего слияния: Исходя из описанной логики перепишем команду слияния merge_cmd
следующим образом: 2) Отредактируем .gitconfig
3) Создадим конфликт при слиянии двух веток (см. пример с использованием DiffMerge). Для разрешения конфликта при слиянии веток, воспользуемся командой |
Сравнение двух файлов в терминале linux (6)
Вот мое решение для этого:
Mkdir temp mkdir results cp /usr/share/dict/american-english ~/temp/american-english-dictionary cp /usr/share/dict/british-english ~/temp/british-english-dictionary cat ~/temp/american-english-dictionary | wc -l > ~/results/count-american-english-dictionary cat ~/temp/british-english-dictionary | wc -l > ~/results/count-british-english-dictionary grep -Fxf ~/temp/american-english-dictionary ~/temp/british-english-dictionary > ~/results/common-english grep -Fxvf ~/results/common-english ~/temp/american-english-dictionary > ~/results/unique-american-english grep -Fxvf ~/results/common-english ~/temp/british-english-dictionary > ~/results/unique-british-english
Есть два файла с именем «a.txt» и «b.txt», у которых есть список слов. Теперь я хочу проверить, какие слова добавлены в «a.txt» и не находятся в «b.txt» .
Мне нужен эффективный алгоритм, так как мне нужно сравнить два словаря.
Вы можете использовать инструмент diff в linux для сравнения двух файлов. Для фильтрации требуемых данных вы можете использовать опции --changed-group-format и --unchanged-group-format .
Следующие три варианта могут использовать для выбора соответствующей группы для каждой опции:
"% <" получить строки из FILE1
"%>" получает строки из FILE2
"" (пустая строка) для удаления строк из обоих файлов.
[ tmp]# cat file1.txt test one test two test three test four test eight [ tmp]# cat file2.txt test one test three test nine [ tmp]# diff --changed-group-format="%<" --unchanged-group-format="" file1.txt file2.txt test two test four test eightНапример: diff --changed-group-format = "% <" --unchanged-group-format = "" file1.txt file2.txt
Если вы предпочитаете стиль вывода diff из git diff , вы можете использовать его с флагом --no-index для сравнения файлов не в репозитории git:
Git diff --no-index a.txt b.txt
Используя пару файлов с строками имени файла размером 200 тыс. В каждом, я сравнивал (со встроенной командой time) этот подход и некоторые другие ответы здесь:
Git diff --no-index a.txt b.txt # ~1.2s comm -23 <(sort a.txt) <(sort b.txt) # ~0.2s diff a.txt b.txt # ~2.6s sdiff a.txt b.txt # ~2.7s vimdiff a.txt b.txt # ~3.2s
comm кажется, является самым быстрым на сегодняшний день, тогда как git diff --no-index представляется самым быстрым подходом для вывода в стиле diff.
Обновление 2018-03-25 Фактически вы можете опустить флаг --no-index если вы не находитесь в репозитории git и хотите сравнить невоспроизводимые файлы в этом репозитории. С man-страниц :
Эта форма предназначена для сравнения данных двух путей в файловой системе. Вы можете опустить параметр -no-index при запуске команды в рабочем дереве, контролируемом Git, и по крайней мере одну из точек пути за пределами рабочего дерева или при запуске команды за пределами рабочего дерева, управляемого Git.
Используйте comm -13 (требуется отсортированные файлы) :
$ cat file1 one two three $ cat file2 one two three four $ comm -13 <(sort file1) <(sort file2) four
Сортируйте их и используйте comm:
Comm -23 <(sort a.txt) <(sort b.txt)
comm сравнивает (сортирует) входные файлы и по умолчанию выводит три столбца: строки, которые уникальны для a, строки, которые являются уникальными для b, и строки, которые присутствуют в обоих. Указав -1 , -2 и / или -3 вы можете подавить соответствующий вывод. Поэтому comm -23 ab перечисляет только записи, которые являются уникальными для a. Я использую синтаксис <(...) для сортировки файлов на лету, если они уже отсортированы, вам это не нужно.
если у вас установлен vim, попробуйте следующее:
Vimdiff file1 file2
Vim -d file1 file2
вы найдете его фантастическим.
В операционной системе Linux есть несколько программных решений для сравнения внутреннего содержимого двух файлов различными методами. Безусловно, такая функция будет безумно полезна веб-разработчику для сравнения двух текстовых файлов. К примеру, есть 2 файла стилей css, которые Вам нужно быстро сравнить чтобы найти в них отличия. Или посмотреть, что нового в обновленном PHP скрипте.
Наглядный пример из жизни:
Итак, в моём случае мне нужно сравнить 2 файла bootstrap.css . Летом сего года я что-то исправил в стилях файла bootstrap.css (чего делать нельзя было, т.к. для кастомных правок стилей нужно использовать отдельный style.css). Из-за этой мелочи мне проблематично обновиться с версии 3.3.2 до bootstrap 3.3.5, т.к. в более новой версии свой обнолённый CSS файл, при замене которого все мои правки пропадут и "слетит" часть дизайна веб-сайта. Учитывая, что в файле стилей bootstrap более 6000 строчек кода абсолютно невозможно самостоятельно просмотреть изменения.Сравниваем файлы с утилитой diff в linux:
Чтобы сравнить файлы `bootstrap.css" и `bootstrap-original.css" (для наглядности переименовал оригинальный файл, дописав к нему приставочку -original), введите в терминале: $ diff bootstrap.css bootstrap-original.css В консоли мы получили стандартный отчет о различиях в этих файлах. Если нужно автоматически сохранить отчет в отдельный файл на диске - направляем вывод результатов diff в файл $ diff bootstrap.css bootstrap-original.css > сss-modifications.diff Теперь весь отчет о различиях файлов сохранится в этот же папке под именем "сss-modifications.diff ". Однако, такой вывод не слишком наглядно показывает где и что было добавлено или убрано мною. Чтобы яснее увидеть чем отличаются два файла, можно использовать sdiff ; Отличие этого пакета в том, что он не генерирует отчёт о различиях. Расположив оба файла в две колонки, он сразу же показывает отличия в обоих файлах. `|" помечает строки, которые различаются между собой `" подсвечивает строки, которые встречаются только во втором файле.Синтаксис команды аналогичен синтаксису diff:
$ sdiff bootstrap.css bootstrap-original.css Выводим в консоль различия, а командой: $ sdiff bootstrap.css bootstrap-original.css > сss-modifications.diff Записываем весь отчёт в отдельном файле. Я бы еще посоветовал дописать аргумент -t, для более читабельного формата diff отчёта (достигается путем выравнивания расстояний между таблицами пробелами). В противном случае в gedit стандартный отчет откроется отлично, а в Sublime он "расплывётся": $ sdiff bootstrap.css bootstrap-original.css > сss-modifications.diff -t P.S. на этом возможности сравнения файлов в Linux не заканчиваются и можно сравнить даже 3 файла одновременно. Для этого используйте команду Для одновременного сравнения трех файлов используйте diff3. $ diff3 bootstrap.css bootstrap-original.css bootstrap-3.css > new.diffОбычно diff генерирует вывод следующего формата:
$ diff file1 file2 2c2 < Helllo --- > Hello
Но существует специальный параметр командной строки (-y), который сообщает утилите о необходимости вывода данных в двух отдельных столбцах. А это пример такого вывода:
$ diff -y file1 file2 Hi Hi Helllo | Hello Bye Bye
Очевидно, что при использовании данного формата вывода символ "|" используется для маркировки отличающихся строк.
5. Сокрытие идентичных строк
Если вы внимательно рассмотрите вывод из предыдущего примера (из расположенного выше раздела 4), вы обнаружите, что при использовании параметра командной строки -y утилита diff выводит не только измененные, но и идентичные строки обрабатываемых файлов. В том случае, если вам нужно убрать идентичные строки из вывода, вы можете воспользоваться параметром --suppress-common-lines .
$ diff -y --suppress-common-lines file1 file2 Helllo | Hello
6. Вывод имен функций языка C, содержащих измененный код
При использовании утилиты diff для сравнения двух файлов исходного кода на языке C может использоваться специальный параметр (-p), который сообщает утилите о необходимости вывода имен функций, в коде которых были обнаружены изменения. Например, предположим, что требуется сравнить два следующих файла исходного кода на языке C:
Файл с именем file1.c:
#include
Файл с именем file2:
#include
Это результат обычного сравнения этих файлов:
$ diff file1.c file2.c 5c5 < if(x == y) // некорректный способ сравнения --- > if(x == y)
А это результат сравнения тех же файлов с использованием параметра -p:
$ diff -p file1.c file2.c *** file1.c 2016-12-29 11:45:36.587010816 +0530 --- file2.c 2016-12-29 11:46:39.823013274 +0530 *************** *** 2,8 **** void compare(float x, float y) { ! if(x == y) // некорректный способ сравнения { printf("\n РАВНЫ \n"); } --- 2,8 ---- void compare(float x, float y) { ! if(x == y) { printf("\n РАВНЫ \n"); }
Очевидно, что в случае использования параметра командной строки -p diff генерирует более подробный вывод с маркировкой измененных строк с помощью символа восклицательного знака ("!").
7. Рекурсивное сравнение содержимого поддиректорий
Утилита diff также позволяет осуществлять рекурсивное сравнение содержимого поддиректорий, но этот режим работы не активирован по умолчанию. Я подразумевал, что при использовании данной команды:
$ diff diff-files/ second-diff-files/ diff diff-files/file1 second-diff-files/file1 1c1 < Hi --- > i diff diff-files/file2 second-diff-files/file2 2c2 < Hello --- > ello
утилита diff будет осуществлять сравнение лишь файлов из директорий верхнего уровня, но в случае использования параметра -r (активирующего режим рекурсивного сравнения файлов) будет осуществляться сравнение даже тех файлов, которые находятся в поддиректориях:
$ diff -r diff-files/ second-diff-files/ diff -r diff-files/file1 second-diff-files/file1 1c1 < Hi --- > i diff -r diff-files/file2 second-diff-files/file2 2c2 < Hello --- > ello diff -r diff-files/more-diff-files/file1 second-diff-files/more-diff-files/file1 1c1 < Hi --- > i diff -r diff-files/more-diff-files/file2 second-diff-files/more-diff-files/file2 2c2 < Hello --- > ello
8. Обработка отсутствующих файлов как пустых
Утилита diff также поддерживает параметр, с помощью которого вы можете сообщить ей о том, что следует рассматривать отсутствующие файлы как пустые. Если вы сравните файлы с именами file1 и file3 (причем последнего файла не существует), по умолчанию diff выведет сообщение об ошибке:
$ diff file1 file3 diff: file3: Нет такого файла или каталога
В этом нет ничего плохого; по сути, данное поведение является вполне обоснованным. Но бывают случаи, когда необходимо избежать вывода сообщений об ошибках (возможно, при использовании diff в рамках сценариев командной оболочки), в которых вы можете воспользоваться параметром -N для обработки отсутствующих файлов как пустых и продолжения сравнения файлов.
$ diff -N file1 file3 1,5d0 < Hi < < Helllo < < Bye
Заключение
Если вы внимательно прочитали обе статьи серии и самостоятельно повторили все рассмотренные в них примеры команд, то вполне можно сказать, что вы овладели всеми основными навыками работы с рассматриваемой утилитой. Конечно же, мы не смогли бы обсудить все связанные с diff вопросы в рамках нескольких статей, но все же все основные возможности и функции данной утилиты были так или иначе упомянуты в них.
Если вы хотите узнать немого больше о данной утилите, вы всегда можете обратиться к ее странице руководства . Думаю, не стоит лишний раз упоминать о том, что вы должны периодически использовать утилиту с различными наборами параметров для симуляции различных рабочих ситуаций.
Селфи палки — что это и какие они бывают Лучшие приложения для селфи
Получение Root LG L70 (D325)
Как найти ролик на ютубе, если не знаешь названия
Почему упал ФПС в World of Tanks
Читы на слитки в скайриме - как получить слитки в игре