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

Другие вопросы по тегам