Поэтому я хочу сравнить два файла строка за столбцом 2. Как я могу это сделать?
File_1.txt:
User1 US
User2 US
User3 US
File_2.txt:
User1 US
User2 US
User3 NG
Выходной файл:
User3 has changed
command-line
text-processing
Roboman1723
источник
источник
diff "File_1.txt" "File_2.txt"
Ответы:
Посмотри в
diff
команду. Это хороший инструмент, и вы можете прочитать все об этом, набравman diff
в своем терминале.Команда, которую вы захотите сделать,
diff File_1.txt File_2.txt
выведет разницу между ними и должна выглядеть примерно так:Краткое примечание о прочтении вывода третьей команды: «стрелки» (
<
и>
) относятся к значению строки в левом файле (<
) по сравнению с правым файлом (>
), причем левый файл - тот, который вы ввели сначала в командной строке, в этом случаеFile_1.txt
Кроме того, вы можете заметить, что 4-ая команда
diff ... | tee Output_File
передает эти результатыdiff
в atee
, который затем помещает этот вывод в файл, так что вы можете сохранить его на потом, если не хотите просматривать все это на консоли прямо в эту секунду.источник
diff file1 file2 -s
. Вот пример: imgur.com/ShrQx9xИли вы можете использовать Meld Diff
Установить, запустив:
Ваш пример:
Сравнить каталог:
Пример с полным текстом:
источник
Вы можете использовать vimdiff .
Пример:
источник
dos
а второй -unix
.FWIW, мне скорее нравится то, что я получаю с параллельным выводом из diff
дал бы что-то вроде:
источник
Вы можете использовать команду
cmp
:выход будет
источник
cmp
гораздо быстрее, чемdiff
если бы все, что вам нужно, это код возврата.Meld
это действительно отличный инструмент. Но вы также можете использоватьdiffuse
для визуального сравнения двух файлов:источник
Придерживаясь вопроса (file1, file2, outputfile с сообщением «изменилось»), скрипт ниже работает.
Скопируйте скрипт в пустой файл, сохраните его как
compare.py
, сделайте его исполняемым, запустите его командой:Сценарий:
С помощью нескольких дополнительных строк вы можете сделать вывод либо в выходной файл, либо в терминал, в зависимости от того, определен ли выходной файл:
Чтобы распечатать в файл:
Чтобы распечатать в окне терминала:
Сценарий:
источник
Простым способом является использование
colordiff
, которое ведет себя как,diff
но окрашивает его вывод. Это очень полезно для чтения различий. Используя ваш пример,где
u
опция дает унифицированный дифференциал Вот как выглядит цветная разница:Установить
colordiff
, запустивsudo apt-get install colordiff
.источник
Дополнительный ответ
Если нет необходимости знать, какие части файлов различаются, вы можете использовать контрольную сумму файла. Есть много способов сделать это, используя
md5sum
илиsha256sum
. По сути, каждый из них выводит строку, к которой относится хэш содержимого файла. Если два файла одинаковы, их хэш будет одинаковым. Это часто используется при загрузке программного обеспечения, такого как установочные образы Ubuntu. Они часто используются для проверки целостности загруженного контента.Рассмотрим скрипт ниже, где вы можете указать два файла в качестве аргументов, и файл сообщит вам, являются ли они одинаковыми или нет.
Образец прогона:
Старый ответ
Кроме того, есть
comm
команда, которая сравнивает два отсортированных файла и выдает выходные данные в 3 столбцах: столбец 1 для элементов, уникальных для файла № 1, столбец 2 для элементов, уникальных для файла № 2, и столбец 3 для элементов, присутствующих в обоих файлах.Для подавления любого столбца вы можете использовать переключатели -1, -2 и -3. Использование -3 покажет линии, которые отличаются.
Ниже вы можете увидеть скриншот команды в действии.
Существует только одно требование - файлы должны быть отсортированы для их правильного сравнения.
sort
Команда может быть использована для этой цели. Ниже приведен скриншот, где файлы сортируются, а затем сравниваются. Строки, начинающиеся с левого столбца только для File_1, строки, начинающиеся со столбца 2, принадлежат только File_2источник
Установите git и используйте
И вы получите вывод в хорошем цветном формате
Git установка
источник
colcmp.sh
Сравнивает пары имя / значение в 2 файлах в формате
name value\n
. Записываетname
вOutput_file
случае изменилась. Требуется bash v4 + для ассоциативных массивов .использование
Выходной файл
Источник (colcmp.sh)
объяснение
Разбивка кода и что это значит, насколько я понимаю. Я приветствую правки и предложения.
Сравнение основных файлов
CMP будет устанавливать значение $? следующим образом :
Я решил использовать регистр . Esac для вычисления $? потому что значение $? изменяется после каждой команды, включая тест ([).
В качестве альтернативы я мог бы использовать переменную для хранения значения $? :
Выше делает то же самое, что и утверждение дела. ИДК, который мне нравится больше.
Очистить вывод
Выше очищает выходной файл, поэтому, если ни один пользователь не изменился, выходной файл будет пустым.
Я делаю это внутри инструкций case, чтобы файл Output_file оставался неизменным при ошибке.
Скопируйте файл пользователя в сценарий оболочки
Выше копирует File_1.txt в домашнюю директорию текущего пользователя.
Например, если текущий пользователь является пользователем john, приведенное выше будет таким же, как cp "File_1.txt" /home/john/.colcmp.arrays.tmp.sh
Побег Специальные персонажи
По сути, я параноик. Я знаю, что эти символы могут иметь особое значение или выполнять внешнюю программу при запуске в сценарии как часть назначения переменной:
Чего я не знаю, так это того, как много я не знаю о bash. Я не знаю, какие другие символы могут иметь особое значение, но я хочу избежать их всех с помощью обратной косой черты:
sed может сделать гораздо больше, чем сопоставление с шаблоном регулярного выражения . Шаблон сценария "s / (find) / (replace) /" специально выполняет сопоставление шаблона.
"S / (поиск) / (заменить) / (модификаторы)"
на английском языке: запишите любую пунктуацию или специальный символ в качестве группы будущего 1 (\\ 1)
по-английски: префикс всех специальных символов с обратной косой чертой
на английском: если в одной строке найдено более одного совпадения, замените их все
Закомментируйте весь скрипт
Выше используется регулярное выражение для префикса каждой строки ~ / .colcmp.arrays.tmp.sh с символом комментария bash ( # ). Я делаю это потому, что позже я намереваюсь выполнить ~ / .colcmp.arrays.tmp.sh, используя команду source, и потому что я точно не знаю весь формат File_1.txt .
Я не хочу случайно выполнять произвольный код. Я не думаю, что кто-то делает.
"S / (поиск) / (заменить) /"
на английском: запишите каждую строку как группу будущего 1 (\\ 1)
на английском: замените каждую строку символом фунта, за которым следует строка, которая была заменена
Преобразовать значение пользователя в A1 [User] = "value"
Выше ядро этого скрипта.
#User1 US
A1[User1]="US"
A2[User1]="US"
(для 2-го файла)"S / (поиск) / (заменить) /"
по-английски:
захватить остальную часть линии в качестве группы захвата 2
(заменить) = A1 \\ [\\ 1 \\] = \ "\\ 2 \"
A1[
для начала назначения массива в массиве с именемA1
]="
]
= закрыть присвоение массива, например,A1[
User1]="
US"
=
= оператор присваивания, например, переменная = значение"
= значение кавычки для захвата пробелов ... хотя теперь, когда я думаю об этом, было бы проще позволить приведенному выше коду, который ставит обратную косую черту, также и символы обратной косой черты.на английском: замените каждую строку в формате
#name value
оператором присваивания массива в форматеA1[name]="value"
Сделать исполняемым
Выше используется chmod, чтобы сделать исполняемый файл скрипта массива.
Я не уверен, если это необходимо.
Объявить ассоциативный массив (bash v4 +)
Заглавная -A указывает, что объявленные переменные будут ассоциативными массивами .
Вот почему скрипт требует bash v4 или выше.
Выполните наш скрипт назначения переменных массива
Мы уже:
User value
в строкиA1[User]="value"
,Выше мы поставили скрипт для запуска в текущей оболочке. Мы делаем это, чтобы сохранить значения переменных, которые устанавливаются сценарием. Если вы выполняете сценарий напрямую, он порождает новую оболочку, и значения переменных теряются при выходе из новой оболочки, или, по крайней мере, я так понимаю.
Это должно быть функцией
Мы делаем то же самое для $ 1 и A1, что мы делаем для $ 2 и A2 . Это действительно должно быть функцией. Я думаю, что на данный момент этот сценарий достаточно запутан и работает, поэтому я не собираюсь его исправлять.
Определить удаленных пользователей
Выше циклы через ключи ассоциативного массива
Выше используется подстановка переменных, чтобы обнаружить разницу между значением, которое не установлено, и переменной, для которой явно задана строка нулевой длины.
По-видимому, есть много способов увидеть, была ли установлена переменная . Я выбрал ту, которая получила наибольшее количество голосов.
Выше добавляет пользователя $ i в Output_File
Определить пользователей, добавленных или измененных
Выше очищает переменную, чтобы мы могли отслеживать пользователей, которые не изменились.
Выше циклы через ключи ассоциативного массива
Выше используется подстановка переменных, чтобы увидеть, была ли установлена переменная .
Поскольку $ i - это ключ массива (имя пользователя), $ A2 [$ i] должен возвращать значение, связанное с текущим пользователем, из File_2.txt .
Например, если $ i равен User1 , приведенное выше читается как $ {A2 [User1]}
Выше добавляет пользователя $ i в Output_File
Поскольку $ i является ключом массива (имя пользователя), $ A1 [$ i] должен возвращать значение, связанное с текущим пользователем, из File_1.txt , а $ A2 [$ i] должно возвращать значение из File_2.txt .
Выше сравниваются связанные значения для пользователя $ i из обоих файлов.
Выше добавляет пользователя $ i в Output_File
Выше создается разделенный запятыми список пользователей, которые не изменились. Обратите внимание, что в списке нет пробелов, иначе нужно будет заключить следующую проверку в кавычки.
Выше сообщается о значении $ USERSWHODIDNOTCHANGE, но только если есть значение в $ USERSWHODIDNOTCHANGE . Как это написано, $ USERSWHODIDNOTCHANGE не может содержать пробелов. Если для этого нужны пробелы, вышеприведенное можно переписать следующим образом:
источник