2

最近我正在编写一个 bash 命令行脚本来维护特定文件夹的大小。请注意,某些程序有时会在此文件夹中写入/更新文件,因此“包罗万象”的 rm -rf 永远不适合这种情况。

我能够检索所有“活动”,换句话说,使用 lsof 打开文件并使用 awk 将它们打印出来:

lsof +D ./ | awk ' { print ( $NF ) } '

这给了我这些打开文件的列表,我显然不想摆脱它们。但是我想删除其余的。

我希望 rm 命令中有一个选项可以使用 ^ 选项排除某些文件...

有没有办法在 bash 中实现这一点?

提前非常感谢。

4

2 回答 2

4

这可以在没有临时文件的情况下在一行上完成,但我会将其拆分以使注释和调试更容易:

# Get a sorted list of used files
lsof +D ./ | awk ' { print ( $NF ) } ' | sort | uniq > usedFiles

# Get a sorted list of existing files
find ./ | sort > existingFiles

# Find lines unique to existingFiles
comm -23 existingFiles usedFiles > removableFiles

# Delete them
rm $(< removableFiles)

请注意,这不是空格安全的。

于 2013-03-04T23:19:33.143 回答
1

首先确保你有extglob

shopt -s extglob

然后删除所有未列出的文件lsof

DONT_RM=`lsof +D \. | awk '{ print $NF; }' | tr "\\n" "|" | sed 's/\.\///g'` && rm !($DONT_RM)

分解上述内容,我们将lsof使用管道|而不是换行符连接结果,\n并从文件名的开头删除前缀./。然后我们将这个 OR 文件列表作为非!extglob 选项传递给 rm。试试看,它适用于我的基本测试。

于 2013-03-05T00:11:21.483 回答