代码之家  ›  专栏  ›  技术社区  ›  brice

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

  •  18
  • brice  · 技术社区  · 15 年前

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

    我试着建立一个 find ./ ! -name "filename" 动态命令:

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

    但文件仍然存在。

    [注:]I know this uses echo.我想在使用命令之前检查它的功能。

    解决方案: (谢谢 PixelBeat )

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

    不带临时文件:

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

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

    5 回复  |  直到 15 年前
        1
  •  12
  •   pixelbeat    15 年前

    使用“设置差异”模式 http://www.pixelbeat.org/cmdline.html#sets

    (find ./ -type f -printf "%P\n"; cat MANIFEST MANIFEST; echo MANIFEST) |
      sort | uniq -u | xargs -r rm
    

    注意,我列出清单两次,以防列出的文件实际上不存在。 还要注意,上面支持子目录中的文件

        2
  •  13
  •   Jürgen Hötzel    15 年前

    为每个 文件 在当前目录中 格雷普 清单文件中的文件名和 RM 文件 如果不匹配。

    for file in *
      do grep -q -F "$file" PATH_TO_YOUR_MANIFIST ||  rm "$file" 
    done
    
        3
  •  4
  •   brice    15 年前

    明白了:

    ls -1 > ALLFILES
    comm -3 MANIFEST ALLFILES | xargs rm
    
        4
  •  1
  •   DVK    15 年前

    只是为了好玩,一个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
    
        5
  •  0
  •   Dennis Williamson    15 年前

    假设清单已排序:

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