我有一个长文本文件,其中包含我要删除的文件掩码列表
示例:
/tmp/aaa.jpg
/var/www1/*
/var/www/qwerty.php
我需要删除它们。试过rm`cat 1.txt`,它说列表太长了。
找到此命令,但是当我从列表中检查文件夹时,其中一些文件夹仍有文件
xargs rm <1.txt
手动rm调用会从这些文件夹中删除文件,因此权限没有问题。
答案 0 :(得分:90)
这不是很有效,但是如果你需要glob模式(如在/ var / www / *中)那么它将起作用
for f in $(cat 1.txt) ; do
rm "$f"
done
如果你没有任何模式,并确保文件中的路径不包含空格或其他奇怪的东西,你可以像这样使用xargs:
xargs rm < 1.txt
答案 1 :(得分:47)
假设文件列表在文件1.txt
中,请执行:
xargs rm -r <1.txt
-r
选项导致递归到1.txt
中命名的任何目录。
如果任何文件是只读的,请使用-f
选项强制删除:
xargs rm -rf <1.txt
对任何执行程序删除的工具的输入要谨慎。使某些确实要删除输入文件中指定的文件。看似简单的拼写错误要特别小心。例如,如果在文件及其后缀之间输入空格,则它将显示为两个单独的文件名:
file .txt
实际上是两个单独的文件:file
和.txt
。
这可能看起来不那么危险,但如果错字是这样的话:
myoldfiles *
然后,您不会删除所有以myoldfiles
开头的文件,而是会删除当前目录中的myoldfiles
和所有非点文件和目录。可能不是你想要的。
答案 2 :(得分:14)
使用此:
while IFS= read -r file ; do rm -- "$file" ; done < delete.list
如果您需要全局展开,可以省略引用$file
:
IFS=""
while read -r file ; do rm -- $file ; done < delete.list
但要注意文件名可以包含“有问题”的内容,我会使用不带引号的版本。想象一下文件中的这种模式
*
*/*
*/*/*
这会从当前目录中删除很多内容!我鼓励你以不再需要glob模式的方式准备删除列表,然后像我的第一个例子中那样使用引用。
答案 3 :(得分:13)
xargs -I{} sh -c 'rm {}' < 1.txt
应该做你想做的事。请小心使用此命令,因为该文件中的一个错误条目可能会导致很多麻烦。
在@tdavies指出原始版本没有进行shell扩展之后编辑了这个答案。
答案 4 :(得分:13)
您可以使用&#39; \ n&#39;用于将新行字符定义为分隔符。
xargs -d '\n' rm < 1.txt
小心使用-rf,因为如果1.txt包含带空格的路径,它可以删除你不想要的内容。这就是新线分隔符更安全的原因。
在BSD系统上,您可以使用-0选项将新行字符用作分隔符,如下所示:
xargs -0 rm < 1.txt
答案 5 :(得分:12)
你可以使用这个单行:
cat 1.txt | xargs echo rm | sh
shell扩展但执行rm
的次数最少。
答案 6 :(得分:4)
cat 1.txt | xargs rm -f | bash
运行该命令将仅对文件执行以下操作。
cat 1.txt | xargs rm -rf | bash
运行该命令将执行以下递归行为。
答案 7 :(得分:3)
在这种特殊情况下,由于其他答案中引用的危险,我会
编辑例如Vim和:%s/\s/\\\0/g
,用反斜杠转义所有空格字符。
然后:%s/^/rm -rf /
,在命令前加上。使用-r
,您不必担心在其中包含的文件后列出目录,并且-f
它不会因丢失文件或重复条目而抱怨。
运行所有命令:$ source 1.txt
答案 8 :(得分:1)
这是另一个循环示例。这个还包含一个“if-statement”字样&#39;作为检查条目是否为“&#39;文件”的示例。 (或者&#39;目录&#39;例如):
for f in $(cat 1.txt); do if [ -f $f ]; then rm $f; fi; done
答案 9 :(得分:0)
此处您可以使用 deletelist.txt 中的一组文件夹,而避免使用某些模式
foreach f (cat deletelist.txt)
rm -rf ls | egrep -v "needthisfile|*.cpp|*.h"
end
答案 10 :(得分:0)
这将允许文件名具有空格(可重现的示例)。
# Select files of interest, here, only text files for ex.
find -type f -exec file {} \; > findresult.txt
grep ": ASCII text$" findresult.txt > textfiles.txt
# leave only the path to the file removing suffix and prefix
sed -i -e 's/:.*$//' textfiles.txt
sed -i -e 's/\.\///' textfiles.txt
#write a script that deletes the files in textfiles.txt
IFS_backup=$IFS
IFS=$(echo "\n\b")
for f in $(cat textfiles.txt);
do
rm "$f";
done
IFS=$IFS_backup
# save script as "some.sh" and run: sh some.sh
答案 11 :(得分:0)
只需提供另一种方法,您也可以简单地使用以下命令
$ cat to_remove
/tmp/file1
/tmp/file2
/tmp/file3
$ rm $( cat to_remove )
答案 12 :(得分:0)
如果有人更喜欢sed
并删除而没有通配符扩展:
sed -e "s/^\(.*\)$/rm -f -- \'\1\'/" deletelist.txt | /bin/sh
提醒:在文件中使用绝对路径名,或确保您在正确的目录中。
为完整起见,与awk
相同:
awk '{printf "rm -f -- '\''%s'\''\n",$1}' deletelist.txt | /bin/sh
如果除去单引号,通配符扩展将起作用,但是如果文件名包含空格,这将很危险。这将需要在通配符周围添加引号。