生成脚本以删除文件列表

-5 linux bash shell

我有一个文件,其中包含我要删除的路径列表.

rm在每个路径前添加(以生成将运行这些删除的脚本)似乎是显而易见的方法.我怎样才能做到这一点?

Cha*_*ffy 6

通过预先添加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)