以交互方式从列表中删除文件

以交互方式从列表中删除文件

我想删除文件列表并要求我确认。该列表位于list.txt文件中。为什么下面的命令不能正常工作?

while read i; do rm -i $i; done < list.txt

前面的命令不会等待我,但幸运的是没有文件被删除。

我正在使用 Bash。

答案1

rm -i从标准输入读取答案,该答案是从while循环继承的。因此,来自的一行文本list.txt被用作“真的删除吗?”的答案。问题。要解决此问题,您需要将两个输入源分开。最简单的方法是read从单独的文件描述符获取输入:

while IFS= read <&3 -r i; do
  rm -i -- "$i"     # Quote the file name, not just to be safe,
                    # but because it's the right syntax.
done 3< list.txt

您不再为 while 循环重定向标准输入 (fd 0),因此rm将根据需要从终端读取。

或者,你也可以这样做:

IFS=$'\n' # set field separator to newline
set -f    # disable globbing upon command substitution
rm -i -- $(cat list.txt)

或者,使用 GNU xargs:

xargs -rd '\n' --arg-file=list.txt rm -i --

答案2

对于比对每个文件回答是或否更奇特的事情,您可以使用iselect基于 ncurses 的交互式选择。例如

iselect -a -m < list.txt | xargs -d '\n' -r echo rm 

或允许选择当前目录中的文件:

find . -maxdepth 1 -type f | iselect -a -m | xargs -d '\n' -r echo rm

这将显示一个全屏(全终端)基于 ncurses 的列表,其中可以通过按空格键随意选择和取消选择文件。按 ENTER 接受您的选择(所选条目将打印在标准输出上),或q退出(不打印任何内容到标准输出上)。按h寻求帮助。

请注意echo rm- 我已经这样编写以进行测试。rm一旦您确信自己了解了它在做什么,就将其更改为。

另请注意,xargs此处使用 with\n作为输入分隔符。如果任何文件名中包含换行符,则此操作将不起作用。就此而言,它iselect也无法正常工作 - 它需要每行一个项目 - 不幸的是,iselect没有空终止输入或输出的选项。

iselect是为 debian 打包的,可能还有 ubuntu 和其他发行版。主页位于http://www.ossp.org/pkg/tool/iselect/

相关内容