Как я могу заставить '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.