Как я могу заставить 'diff' показывать только добавленные и удаленные строки? Если diff не может этого сделать, какой инструмент может? Take-2
У меня есть 2 отсортированные файлы, созданные
xxx> find / store -type f -print | sort> /tmp/invent.txt xxx> find / fbkup -type f -print | sort> /tmp/backup.txt
Я хочу из diff список имен файлов, отсутствующих в / store, которые все еще находятся в / backup, без каких-либо аннотаций <>, только один выходной файл, содержащий точно такие же записи из / tmp / backup, для которых не было совпадений в / tmp /invent.txt.
xxx> diff -??? /tmp/invent.txt /tmp/invent.txt | XARGS...
4 ответа
Разберитесь со своими файлами, затем используйте awk, чтобы найти нужные строки (/^<
), лишить ведущий бит (gsub(/^</,"")
) и выведите соответствующую строку.
diff file1 file2 | awk '/^</ {gsub(/^</,""); print}'
Так что если вы хотите один лайнер, вы можете сделать что-то вроде этого.
diff <(cd /store ; find . -type f -print | sort) \
<(cd /fbkup ; find . -type f -print | sort) | \
awk '/^</ {gsub(/^</,""); print}'
for i in `cat /tmp/invent.txt`; do grep ^$i$ /tmp/backup.txt >/dev/null || echo $i ; done
Это будет echo
все имена в /tmp/invent.txt
который не в /tmp/backup.txt
редактировать
Я нашел другой способ, используя diff
: - (diff -r dir1 dir2
)
-r, --recursive
средстваRecursively compare any subdirectories found.
$ mkdir -p dir1/dir dir2/dir/dir
$ diff -r dir1 dir2
Only in dir2/dir: dir
$ touch dir1/file{a..d}
$ touch dir2/file{a..d}
$ touch dir2/dir/file{a..d}
$ echo hi > dir2/filea
$ diff -q -r dir1 dir2
Only in dir2/dir: dir
Only in dir2/dir: filea
Only in dir2/dir: fileb
Only in dir2/dir: filec
Only in dir2/dir: filed
Files dir1/filea and dir2/filea differ
Не использовать diff
использовать join
вместо. Поскольку ваши входные файлы уже sort
ed, следующее должно выдавать именно то, что вы запрашивали:
join -v 2 /tmp/invent.txt /tmp/backup.txt > /tmp/in-backup-but-not-invent.txt
(Если пути к файлам в /tmp/backup.txt
или же /tmp/invent.txt
содержать пробелы, то join
может работать некорректно с параметрами, указанными выше. В этом случае вам придется посмотреть на использование -t
опция, чтобы указать непробельный символ в качестве разделителя поля для join
, Вы хотели бы выбрать в качестве разделителя полей символ, который на самом деле не отображается ни в одном из ваших путей к файлам. Что-то вроде |
или же \
вероятно, будет достаточно.)
Дифф может это сделать, но мне лень это проверять.
Пытаться comm
, comm -2 -3
или же comm -1 -2
которые будут давать строки только в файле A или только в файле B.