【问题标题】:Generating a script to delete a list of files生成脚本以删除文件列表
【发布时间】:2015-10-16 19:39:52
【问题描述】:

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

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

【问题讨论】:

  • 回复:“您能尽快给我回复吗?”——这实际上并没有帮助您更快地获得回复。见catb.org/esr/faqs/smart-questions.html#urgent
  • 从这里开始for row in $(cat file); rm $row; done。如果您的行中有空格,这很棘手......
  • @Oerd,这不仅仅是空间的问题——它也会扩大 glob。请参阅mywiki.wooledge.org/BashFAQ/001 了解迭代文件的最佳实践方法,$(cat file) 不是。 (然后在扩展$row 时缺少引用,这会产生自己的错误;然后是每个文件调用外部rm 命令的效率低下,xargs 可以避免)。
  • @Oerd, ...另见mywiki.wooledge.org/BashPitfalls中的条目#1
  • 感谢@Charles 指出这一点,已经多次阅读链接,只是永远无法正确理解xargs :) 很好的答案顺便说一句!

标签: linux bash shell


【解决方案1】:

通过在每行开头添加rm 将文件名列表更改为shell 脚本是危险的做法:文件名在被shell 解释时可能不会映射到自身,甚至可能会产生副作用,包括运行任意命令.不要那样做。


如果要删除一个文件中命名的所有文件,只需使用xargs直接调用rm并传递文件名即可:

xargs rm -f -- <input-file

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

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

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

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

如果您真的想要生成一个 shell 脚本来删除列出的一组名称,顺便说一下,您可以在 bash 中执行此操作,如下所示:

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,并在后者中生成一个安全引用的列表,调用次数最少: p>

{
  echo "#!/bin/bash"
  xargs bash -c 'printf "rm -f -- "; printf "%q " "$@"; printf "\n"'
} <input-file >output-script

【讨论】:

  • @keda,-- 确保所有其他选项都被视为位置;如果你的文件有一行包含-r,你想删除一个名为-r的文件,而不是将其他删除修改为递归。
  • @keda, ...请参阅pubs.opengroup.org/onlinepubs/009696899/basedefs/… POSIX 实用程序约定中的准则 10
【解决方案2】:

你可以使用sed

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

^ 是一行的开头,所以每一行的开头都会被rm 代替。

【讨论】:

  • 这是真的,但是这样做然后运行生成的脚本将是非常糟糕的做法,如果名称不受控制,则会产生重大的安全风险:如果其中一个包含$(rm -rf /),甚至只是一个*,周围有空格?
  • @CharlesDuffy 我同意,但这是对已发布问题的回答。我不想对@Ismail Shaik 的代码做出任何假设。一般来说,rm 是一个不可掉以轻心的危险命令。我的回答提供了基本信息,应该足以让他继续前进。他应该负责确保它是安全的。
  • @CharlesDuffy 但是,我同意你的看法。在执行任何批量rm 命令之前必须采取预防措施。
  • @CharlesDuffy 这是我脑海中闪现的第一件事。它又快又脏,但它有效。您的回答更广泛,最终更安全。现在他有两种方法可供选择。我学到了一些新东西。谢谢!
猜你喜欢
  • 1970-01-01
  • 2021-11-04
  • 2016-08-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多