Unix:如何删除文件中列出的文件

时间:2011-02-28 13:13:08

标签: linux unix

我有一个长文本文件,其中包含我要删除的文件掩码列表

示例:

/tmp/aaa.jpg
/var/www1/*
/var/www/qwerty.php

我需要删除它们。试过rm`cat 1.txt`,它说列表太长了。

找到此命令,但是当我从列表中检查文件夹时,其中一些文件夹仍有文件 xargs rm <1.txt手动rm调用会从这些文件夹中删除文件,因此权限没有问题。

13 个答案:

答案 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)

在这种特殊情况下,由于其他答案中引用的危险,我会

  1. 编辑例如Vim和:%s/\s/\\\0/g,用反斜杠转义所有空格字符。

  2. 然后:%s/^/rm -rf /,在命令前加上。使用-r,您不必担心在其中包含的文件后列出目录,并且-f它不会因丢失文件或重复条目而抱怨。

  3. 运行所有命令:$ 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

如果除去单引号,通配符扩展将起作用,但是如果文件名包含空格,这将很危险。这将需要在通配符周围添加引号。