我有一个文件,其中包含我要删除的路径列表。
在每条路径前添加rm
(生成将运行这些删除的脚本)似乎是一种显而易见的方法。我怎么能这样做?
答案 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
替换。