我最初写了一个命令,以一定的时间间隔定期删除自动生成的 Emacs 文件,从我当前的目录开始(在意识到您可以在 Emacs 中禁用它之前):
#!/bin/sh
clean ()
{
find . -name "*~" -type f | while read f; do rm "$f"; done
}
while true; do clean; sleep 1800; done &
我发现上面的脚本并不总是有效。原因如下:
sh-3.2$ ls
FilenameWithNewLine?End One-Word-Filename Two-Word Filename
sh-3.2$ find . -name "*" -type f
./Two-Word Filename
./One-Word-Filename
./FilenameWithNewLine
End
这引出了我关于解析文件名的最佳方法的问题,特别是关于管铣削。
明确地说,我要求的是一种解析文件名的通用方法。
这是另一个例子:
sh-3.2$ ls > myfilenames.txt
sh-3.2$ cat myfilenames.txt | grep 'mypattern'
由于我提到的相同问题,上述内容不起作用。
我正在寻找一个普遍的答案,并用例子来说明我的观点。
我会做什么:
clean ()
{
find . -name "*~" -type f -delete
}
使用 POSIX
find
,您可以直接调用 rm
:
clean ()
{
find . -name "*~" -type f -exec rm {} +
}
这也适用于更复杂的外壳处理:
find . -name "*~" -type f -exec sh -c '
for f; do
rm "$f"
done
' -- {} +
请记住,如果有大量输入文件名,可能会多次调用
-exec
:
find / -exec sh -c 'echo $#' -- {} + 2>&-
要处理带有嵌入换行符的文件名,您需要一种明确的格式。文件名中不允许有空值,因此使用空值分隔的 I/O 允许安全地处理任意文件名。
如果您不太担心 POSIX 兼容性,一些实用程序的实现支持空分隔输入和/或输出。例如:
find -print0
xargs -0
sort -z
grep -z
awk -v RS='\0'