我有两个目录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
将读取标准输入并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
正确时消除回声。