Определите общие имена подкаталогов в двух разных каталогах и удалите их.

Определите общие имена подкаталогов в двух разных каталогах и удалите их.

У меня есть два каталога dir1, dir2в которых есть сотни подкаталогов в depth 1. Мне нужна только информация об именах подкаталогов, которые являются общими для dir1и , dir2и я систематически удаляю их из dir2. Мне не нужно сравнивать файлы или содержимое файлов. Выполнение

diff -qr dir_one dir_two | sort

также выводит имена файлов, которые меня в данный момент не интересуют.

решение1

В вашем случае вы можете избежатьидентифицироватьобщие каталоги, поскольку rm -rfпросто игнорирует несуществующие.

Так что достаточноfind всекаталоги dir1и удалить их из dir2:

find dir1 -mindepth 1 -maxdepth 1 -type d -printf "dir2/%f\0" |xargs -0 rm -rf --

Некоторые пояснения. По умолчанию findбудут выведены все каталоги с полным путем, который равен dir1. Поэтому мы используем -printfдля вывода только имени файла без ведущих каталогов (%f) плюс другой путь "dir2", где мы хотим удалить. Кроме того, мы завершаем строку нулевым байтом '\0' вместо новой строки, чтобы использовать xargопцию -0, которая делает все это безопасным относительно имен файлов с пробелами. Затем xargsбудет прочитан stdin и выполнена rmкоманда, добавлены все строки в качестве аргументов.

Обратите внимание, что перед тем, как удалить их, вы можете проверить свою командную строку, добавив echoдля вывода только rmкоманды:

find dir1 -mindepth 1 -maxdepth 1 -type d -printf "dir2/%f\0" |xargs -0 echo rm -rf --

Только длясписокобщие каталоги, которые можно использовать lsвместо rm(добавив 2>/dev/null, чтобы игнорировать несуществующие):

find dir1 -mindepth 1 -maxdepth 1 -type d -printf "dir2/%f\0" |xargs -0 -r ls -d -- 2>/dev/null

решение2

comm -1 -3 <( cd dir1 && find -maxdepth 1 -type d | sort ) <( cd dir2 && find -maxdepth 1 -type d | sort ) | ( cd dir2 && xargs rm -rf )

с переносами строк для удобства чтения:

comm -1 -3 <( cd dir1 && find -maxdepth 1 -type d | sort ) \
           <( cd dir2 && find -maxdepth 1 -type d | sort ) \
                | ( cd dir2 && xargs rm -rf )

объяснение

find -maxdepth 1 -type d

перечислить только каталоги без подкаталогов.

cd dir1 && find -maxdepth 1 -type d | sort

сначала перейдите в каталог, а затем выведите список каталогов.

<( ... )

замена процесса.

comm -1 -3 <( ... ) <( ... )

берется первый вход и второй вход и печатаются строки, уникальные для второго входа. По сути, это печатает каталоги, которые есть в , dir2но не в dir1.

... | ( cd dir2 && xargs rm -rf )

изменить рабочий каталог, чтобы dir2затем выполнить команду rm -rfс выводом предыдущей команды в качестве аргументов. по сути, это приведет к удалению каталогов, которые находятся в , dir2но не в dir1.

Сначала выполните проверку, отсоединив трубу xargsи осмотрев выход.

решение3

find dir1 dir2 -maxdepth 2 | egrep '/' | xargs --max-args 1 basename | sort | uniq -c  | egrep -v '^      1 ' | while read n de ; do echo rm -rfv dir2/$de ; done

уберите эхо, если все правильно.

Связанный контент