很多天前,我发现了这个有用的 bash 别名(我的~/.bash_aliases)
# aliases
# finds temporary files ending with '~' and deletes them
alias rm~='find . -name '*~' -print0 | xargs -0 /bin/rm -f'
现在我尝试使用rm~
aftercd
到包含 3 个以 结尾的文件的目录~
我在终端中收到此错误,并且文件未被删除
find: paths must precede expression: 1n.in~
Usage: find [-H] [-L] [-P] [-Olevel] [-D help|tree|search|stat|rates|opt|exec] [path...] [expression]
此外,当我尝试时rm~
,/home/me
它似乎什么也没做。或者它可能需要很长时间。
请告诉我为什么会出现错误,以及如何修复它。
谢谢!
答案1
您的 bash 别名写得不好(单引号使用不当)。 而应该是:
alias rm~='find . -name "*~" -print0 | xargs -0 /bin/rm -f'
现在,我个人不喜欢无用地使用管道和xargs
,因此您的别名最好写成:
alias rm~='find . -name "*~" -type f -exec /bin/rm -fv -- {} +'
选项-type f
以便仅查找文件(而不是目录、链接等),-v
选项rm
以便详细(打印出删除的内容)。最后的+
以便find
运行rm
所有找到的文件(仅生成一个 实例rm
,而不是每个文件一个)。
现在来自man bash
:
对于几乎所有用途来说,别名都被 shell 函数所取代。
最好使用函数,而不是别名:在文件中注释掉你的别名.bash_aliases
(即,#
在该行前面加上一个),然后在文件中.bashrc
加上这个功能(在文件中的任何位置,在最后都可以):
rm~() {
find . -name "*~" -type f -exec /bin/rm -fv -- {} +
}
另外,正如其他答案所提到的,您可以使用命令-delete
来查找。在这种情况下,您的rm~
功能将是:
rm~() {
find . -name "*~" -type f -printf "Removing file %p\n" -delete
}
事实上,你可以创建一个很酷的函数,它接受一个参数,比如说--dry-run
,它只输出它将删除的内容:
rm~() {
case "$1" in
"--dry-run")
find . -name "*~" -type f -printf "[dry-run] Removing file %p\n"
;;
"")
find . -name "*~" -type f -printf "Removing file %p\n" -delete
;;
*)
echo "Unsupported option \`$1'. Did you mean --dry-run?"
;;
esac
}
然后使用如下方式:
rm~ --dry-run
仅显示将被删除的文件(但不删除它们),然后
rm~
当你对此感到满意时。
适应并扩展您的需求!
笔记。您必须打开一个新终端才能使更改生效。
答案2
*~
在分配给您的别名之前,它会被 shell 扩展。实际分配是:
alias rm~='find .name some~ file~ 1n.in~ -print0 | xargs -0 /bin/rm -f'
我建议使用函数而不是别名,函数的功能更强大,而且在引用方面更容易处理。
当我们这样做时,删除多余的部分.
(如果没有给出参数,则暗示当前目录)并停止滥用,xargs
因为-delete
选项已经存在。
rm~() { find -name '*~' -ls -delete; }
该-ls
选项是可选的,但添加它将显示哪些文件已被删除。