我有一个长文本文件,其中包含要删除的文件掩码列表
例:
/tmp/aaa.jpg
/var/www1/*
/var/www/qwerty.php
我需要删除它们。尝试使用rm`cat 1.txt`,它表示列表太长。
找到了此命令,但是当我从列表中检查文件夹时,其中某些文件夹仍包含文件。
xargs rm <1.txt
手动rm调用可从此类文件夹中删除文件,因此权限没有问题。
Answers:
这不是很有效,但是在需要全局模式时可以使用(如/ var / www / *)
for f in $(cat 1.txt) ; do
rm "$f"
done
如果您没有任何模式,并且确定文件中的路径不包含空格或其他奇怪的东西,则可以使用xargs,如下所示:
xargs rm < 1.txt
假设文件列表在file中1.txt
,则执行以下操作:
xargs rm -r <1.txt
该-r
选项将导致递归到以下任何目录中1.txt
。
如果任何文件是只读文件,请使用该-f
选项来强制删除:
xargs rm -rf <1.txt
请谨慎输入执行程序删除的任何工具。请一定在输入文件中指定的文件是真的被删除。特别注意看似简单的错别字。例如,如果在文件及其后缀之间输入一个空格,它将显示为两个单独的文件名:
file .txt
实际上是两个单独的文件:file
和.txt
。
这似乎并不那么危险,但是如果输入错误是这样的:
myoldfiles *
然后,而不是删除打头的所有文件myoldfiles
,你最终会删除myoldfiles
和所有的非点的文件和目录在当前目录。可能不是您想要的。
用这个:
while IFS= read -r file ; do rm -- "$file" ; done < delete.list
如果需要全局扩展,则可以省略引号$file
:
IFS=""
while read -r file ; do rm -- $file ; done < delete.list
但请注意,文件名可能包含“有问题的”内容,我将使用未引用的版本。想象一下文件中的这种模式
*
*/*
*/*/*
这将从当前目录中删除很多内容!我鼓励您以不再需要全局模式的方式准备删除列表,然后像在我的第一个示例中一样使用引号。
/My Dir With Spaces/
/Spaces and globs/*.txt
,此外--file-with-leading-dashes
,它是POSIX,可在GNU / Linux,macOS和BSD上运行。
您可以使用“ \ n”将换行符定义为定界符。
xargs -d '\n' rm < 1.txt
注意-rf,因为如果1.txt包含带空格的路径,它会删除您不需要的内容。这就是为什么新行分隔符更安全的原因。
在BSD系统上,可以使用-0选项将换行符用作分隔符,如下所示:
xargs -0 rm < 1.txt
xargs: illegal option -- d
-0
在OS X
xargs -I_ rm _
也可以在OS X中使用:)请参见stackoverflow.com/a/39335402/266309
-d
),则可以先将换行符转换为null:tr '\n' '\0' < 1.txt | xargs -0 rm
您可以使用这种单线:
cat 1.txt | xargs echo rm | sh
进行外壳扩展,但执行rm
最少次数。
-n <n>
参数以xargs
减少传递给每个rm的参数的数量,但是仍然不能保护您免受单个glob的限制。
xargs -I{} sh -c 'rm {}' < 1.txt
应该做你想做的。请谨慎使用此命令,因为该文件中的一个错误条目可能会引起很多麻烦。
在@tdavies指出原始文件没有进行shell扩展之后,对该答案进行了编辑。
xargs -I{} sh -c 'rm {}' < 1.txt
在这种情况下,由于其他答案中提到的危险,我会
在Vim和中编辑,:%s/\s/\\\0/g
使用反斜杠转义所有空格字符。
然后:%s/^/rm -rf /
,在命令之前。有了-r
您,您不必担心在其中包含的文件之后列出目录,并且-f
不会因缺少文件或重复条目而抱怨。
运行所有命令: $ source 1.txt
这将允许文件名包含空格(可重现的示例)。
# 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