![Unix 删除超过 30 天的文件和文件夹,但跳过一个特定目录以及嵌套在其中的文件/文件夹](https://linux22.com/image/208948/Unix%20%E5%88%A0%E9%99%A4%E8%B6%85%E8%BF%87%2030%20%E5%A4%A9%E7%9A%84%E6%96%87%E4%BB%B6%E5%92%8C%E6%96%87%E4%BB%B6%E5%A4%B9%EF%BC%8C%E4%BD%86%E8%B7%B3%E8%BF%87%E4%B8%80%E4%B8%AA%E7%89%B9%E5%AE%9A%E7%9B%AE%E5%BD%95%E4%BB%A5%E5%8F%8A%E5%B5%8C%E5%A5%97%E5%9C%A8%E5%85%B6%E4%B8%AD%E7%9A%84%E6%96%87%E4%BB%B6%2F%E6%96%87%E4%BB%B6%E5%A4%B9.png)
我正在尝试找到一种方法来删除特定路径中超过 30 天的所有文件和目录。但在该路径中有一个我不想删除或修改的特定目录。我一直在阅读 -prune 但似乎无法让它发挥作用。到目前为止我尝试过的命令是:find "<path to directory" -prune -o -name "<name of excluded directory" -type f -mtime +30 -exec rm {} +
答案1
您的命令逻辑似乎find
混乱了。如果您想排除名为 的目录excludeme
并以其他方式打印文件名,您可以编写:
find /path/to/top/directory -name excludeme -prune -o -type f -print
回想一下,这-o
是一个逻辑OR
,因此任何有效的条件都-prune
需要与-o
命令位于同一侧-prune
。
考虑到这一点,我们最终得到:
find "<path to directory" \
-name "<name of excluded directory> -prune -o \
-type f -mtime +30 -exec rm {} +
答案2
一步法
如果要删除所有文件和目录(不仅仅是文件),则应该保护目录本身,而不仅仅是其目录树中的文件和 d。 (如果只删除文件,问题会更容易。)这可以通过如下方式完成:
让我们假设以下文件结构(借用另一个测试示例),
$ find
.
./tarfile
./work
./work/file1
./work/dir 4
./work/dir 4/file 1
./work/file2
./work/dir5
./work/dir5/sub1
./work/dir5/sub2
./work/ttt
./work/dir1
./work/dir1/file1
./work/dir1/file2
./work/dir1/file 3
./work/dir2
./work/dir2/file1
./work/dir2/file2
./work/dir3
./work/dir3/file1
./work/dir3/file2
./work/dir3/file3
./work/rsync-by-folder
./backup
./backup/dir 4
./backup/dir 4/file 1
./backup/dir1
./backup/dir1/file1
./backup/dir1/file2
./backup/dir1/file 3
./backup/dir2
./backup/dir2/file1
./backup/dir2/file2
./backup/dir3
./backup/dir3/file1
./backup/dir3/file2
./backup/dir3/file3
以下命令行排除目录./work/dir2
(及其路径)并删除其他所有内容(文件和目录),
$ find . -mindepth 1 -maxdepth 2 -mtime +45 -not \( -path ./work -or -path './work/dir2' \) -exec echo rm -r {} +
或(为了每个rm
实例一行)
$ find . -mindepth 1 -maxdepth 2 -mtime +45 -not \( -path ./work -or -path './work/dir2' \) -exec echo rm -r {} \;
rm -r ./work/file1
rm -r ./work/dir 4
rm -r ./work/file2
rm -r ./work/dir5
rm -r ./work/ttt
rm -r ./work/dir1
rm -r ./work/dir3
rm -r ./work/rsync-by-folder
rm -r ./backup
rm -r ./backup/dir 4
rm -r ./backup/dir1
rm -r ./backup/dir2
两步法
一个可能更安全的替代方案是分两步完成(设置 find 命令行时出错的风险较小)。第一步与原始问题和第一个答案中已显示的内容相匹配,删除应受保护的目录树之外的文件。在我的例子中它匹配
$ find . -mtime +45 -not -path '*/dir2/*' -type f -exec rm -r {} +
保留以下文件和目录
$ find -printf "%y %p\n"
d .
f ./tarfile # too new (dangerous location if important to keep)
d ./work
d ./work/dir 4
d ./work/dir5
d ./work/dir5/sub1
d ./work/dir5/sub2
d ./work/dir1
d ./work/dir2
f ./work/dir2/file1
f ./work/dir2/file2
d ./work/dir3
d ./backup
d ./backup/dir 4
d ./backup/dir1
d ./backup/dir2
f ./backup/dir2/file1
f ./backup/dir2/file2
d ./backup/dir3
现在我们删除空目录。下面的方法并不复杂,需要重复直到删除整个空目录树。欢迎您提出更直接的方法。该rm
选项-d
删除空目录。
find -type d -exec rm -d {} +
会有人抱怨有些目录不为空。我们得到以下结果,
$ find -printf "%y %p\n"
d .
f ./tarfile
d ./work
d ./work/dir5 # This is an empty directory
d ./work/dir2
f ./work/dir2/file1
f ./work/dir2/file2
d ./backup
d ./backup/dir2
f ./backup/dir2/file1
f ./backup/dir2/file2
重复:
find -type d -exec rm -d {} +
并检查结果:
$ find -printf "%y %p\n"
d .
f ./tarfile # too new (dangerous location if important to keep)
d ./work
d ./work/dir2
f ./work/dir2/file1
f ./work/dir2/file2
d ./backup
d ./backup/dir2
f ./backup/dir2/file1
f ./backup/dir2/file2
现在目录树只包含应该保护的内容。