生成脚本以删除文件列表

时间:2015-10-16 19:39:52

标签: linux bash shell

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

在每条路径前添加rm(生成将运行这些删除的脚本)似乎是一种显而易见的方法。我怎么能这样做?

2 个答案:

答案 0 :(得分:6)

通过将rm添加到每行的开头来将文件名列表更改为shell脚本是危险的做法:当shell解释时,文件名可能不会映射到自身,甚至可能包含运行的副作用任意命令。别这么做。

如果要删除文件中指定的所有文件,只需使用xargs直接调用rm并传递文件名:

xargs rm -f -- <input-file

请注意,这将使xargs尝试解释名称中的转义字符,引号等;如果你不想要这个,并且有GNU xargs:

xargs -d $'\n' rm -f -- <input-file

同样,如果您可以控制输入文件的格式,则应使用NUL分隔的文件名流,而不是以换行符分隔的名称列表。 (这是因为POSIX文件系统允许文件名中的换行文字)。如果输入文件以null分隔,则可以使用:

xargs -0 rm -f -- <null-delimimted-input-file

如果您确实想要生成一个将删除列出的名称集的shell脚本,那么可以在bash中执行此操作,如下所示:< / p>

while IFS= read -r filename; do
  printf 'rm -f -- %q\n' "$filename"
done <input-list >output-script

使用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

答案 1 :(得分:2)

您可以使用sed

sed 's/^/rm /' foo.sh > foo2.sh

^是一行的开头,因此每行的开头将被rm替换。