Назад | Перейти на главную страницу

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

Различайте файлы, затем используйте 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}'

Не использовать diff, используйте join вместо. Поскольку ваши входные файлы уже sorted, следующее должно дать именно тот результат, который вы запрашивали:

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. Вы хотели бы выбрать в качестве разделителя полей символ, который фактически не отображается ни в одном из ваших путей к файлам. Что-то вроде | или \ наверное хватит.)

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 может это сделать, но мне лень проверять.

Пытаться comm. comm -2 -3 или comm -1 -2 который выдаст строки только в файле A или строки только в файле B.