BASH:如何删除清单中指定的文件以外的所有文件?

时间:2010-05-06 16:12:06

标签: bash unix scripting find

我有一个清单文件,它只是换行符分隔的文件名列表。如何从文件夹中删除清单中所有文件?

我尝试动态构建find ./ ! -name "filename"命令:

command="find ./ ! -name \"MANIFEST\" "
for line in `cat MANIFEST`; do
    command=${command}"! -name \"${line}\" " 
done
command=${command} -exec echo {} \;
$command

但文件仍然存在。

[注意:]我知道这使用echo。我想在使用之前检查一下我的命令。

解决方案:(感谢PixelBeat

ls -1 > ALLFILES
sort MANIFEST MANIFEST ALLFILES | uniq -u | xargs rm

没有临时文件:

ls -1 | sort MANIFEST MANIFEST - | uniq -u | xargs rm

两者都忽略文件是否已排序。

5 个答案:

答案 0 :(得分:14)

对于MANIFEST文件中当前目录 grep 文件名中的每个文件,如果不匹配则 rm 文件。< / p>

for file in *
  do grep -q -F "$file" PATH_TO_YOUR_MANIFIST ||  rm "$file" 
done

答案 1 :(得分:13)

使用http://www.pixelbeat.org/cmdline.html#sets

中的“设置差异”模式
(find ./ -type f -printf "%P\n"; cat MANIFEST MANIFEST; echo MANIFEST) |
  sort | uniq -u | xargs -r rm

注意我列出两次MANIFEST,以防其中列出的文件实际上不存在。 另请注意,上面支持子目录中的文件

答案 2 :(得分:5)

想通了:

ls -1 > ALLFILES
comm -3 MANIFEST ALLFILES | xargs rm

答案 3 :(得分:1)

只是为了好玩,一个Perl 1-liner ......在这种情况下并不是真的需要,但如果你想要更高级的东西,可以比Bash更可定制/可扩展:)

$ ls
1   2   3   4   5   M
$ cat M
1
3
$ perl -e '{use File::Slurp; %M = map {chomp; $_ => 1} read_file("M"); $M{M}=1; \
foreach $f (glob("*")) {next if $M{$f}; unlink "$f"||die "Can not unlink: $!\n" };}' 
$ ls
1   3   M

如果你在STDIN

上传递清单,上面的内容会更短
perl -e '{%M = map {chomp; $_ => 1} <>; $M{M}=1; \
foreach $f (glob("*")) {next if $M{$f};unlink "$f"||die "Can not unlink: $!\n" };}' M

答案 4 :(得分:0)

假设MANIFEST已经排序:

find -type f -printf %P\\n | sort | comm -3 MANIFEST - | xargs rm