通过预先添加rm到每行的开头将文件名列表更改为shell脚本是危险的做法:当shell解释时,文件名可能不会映射到自身,甚至可能有包含运行任意命令的副作用.不要那样做.
如果要删除文件中指定的所有文件,只需使用xargs直接调用rm传递的文件名:
xargs rm -f -- <input-file
Run Code Online (Sandbox Code Playgroud)
请注意,这将使xargs尝试解释名称中的转义字符,引号等; 如果你不想要这个,并拥有GNU xargs:
xargs -d $'\n' rm -f -- <input-file
Run Code Online (Sandbox Code Playgroud)
同样,如果您可以控制输入文件的格式,则应使用NUL分隔的文件名流,而不是以换行符分隔的名称列表.(这是因为POSIX文件系统允许文件名中的换行文字).如果输入文件以null分隔,则可以使用:
xargs -0 rm -f -- <null-delimimted-input-file
Run Code Online (Sandbox Code Playgroud)
如果你真的想要生成一个将删除列出的名称集的shell脚本,那么你可以在bash中执行此操作,如下所示:
while IFS= read -r filename; do
printf 'rm -f -- %q\n' "$filename"
done <input-list >output-script
Run Code Online (Sandbox Code Playgroud)
printf %q以这样的方式使用转义内容,当被bash重读时,它将被解析为其文字内容(因此,在字符之前放置反斜杠*或者$可能以其他方式解释).
也就是说,因为rm每个文件调用一次,所以效率低于xargs(将多个文件名传递给每个rm调用).
这就是说 - 实际上有一个中间立场:你可以xargs调用bash,并在后者中生成一个安全引用的列表,只需要最少的调用次数:
{
echo "#!/bin/bash"
xargs bash -c 'printf "rm -f -- "; printf "%q " "$@"; printf "\n"'
} <input-file >output-script
Run Code Online (Sandbox Code Playgroud)