【问题标题】:Move all files except one移动除一个以外的所有文件
【发布时间】:2010-10-14 19:15:54
【问题描述】:

如何移动除一个以外的所有文件?我正在寻找类似的东西:

'mv ~/Linux/Old/!Tux.png ~/Linux/New/'

我将旧内容移至新内容文件夹,Tux.png 除外。 !-符号表示否定。有适合这项工作的工具吗?

【问题讨论】:

    标签: linux bash glob


    【解决方案1】:

    一种快速的方法是修改 tux 文件名,以便您的移动命令不匹配。

    例如:

    mv Tux.png .Tux.png
    
    mv * ~/somefolder
    
    mv .Tux.png Tux.png
    

    【讨论】:

    • 不要使用“.”,因为这只会移动带有“.”的文件。在名字里。只需“*”就足够了。
    • 如果您将其更改为 *,它也会删除您重命名的文件。
    • @John T:不,* glob 不匹配以点开头的文件。
    【解决方案2】:

    如果您使用 bash 并设置了 extglob shell 选项(通常是这种情况):

    mv ~/Linux/Old/!(Tux.png) ~/Linux/New/
    

    【讨论】:

    • 我在测试许多项目的命令时出错了: mv ~/Linux/Old/!(Tux.png Tux1.png Tux2.png) ~/Linux/New/ 它清空了整个旧目录。怎么了?
    • @UnixBasics,试试:~/Linux/Old/!(Tux.png|Tux1.png|Tux2.png)
    • @Juliano 非常酷的命令!是否有更多的数学运算,如 OR 和 XOR?我假设管道用于 AND。
    • 对于 ZSH 用户,不要使用shopt(这将给出command not found 错误),将其添加到您的.zshrcsetopt extended_glob 然后syntax for glob 也会相应地更改。因此使用mv ~/path/to/source^(exception) ~/path/to/target/folder 应该这样做
    【解决方案3】:
    mv `find Linux/Old '!' -type d | fgrep -v Tux.png` Linux/New
    

    find 命令列出所有常规文件,fgrep 命令过滤掉所有 Tux.png。反引号告诉 mv 移动生成的文件列表。

    【讨论】:

    • 永远不要将 find 作为另一个命令的参数。坏事会发生。您可能刚刚创建了一个漏洞。始终使用 find -print0 | xargs -0 构造,或查找 -exec。
    【解决方案4】:

    对于 bash,sth answer 是正确的。这是zsh(我选择的shell)语法:

    mv ~/Linux/Old/^Tux.png ~/Linux/New/
    

    需要设置EXTENDED_GLOB shell 选项。

    【讨论】:

    • 如果我们想排除两个文件怎么办?
    【解决方案5】:

    我会采用传统的 find & xargs 方式:

    find ~/Linux/Old -maxdepth 1 -mindepth 1 -not -name Tux.png -print0 | 
        xargs -0 mv -t ~/Linux/New
    

    -maxdepth 1 使其不递归搜索。如果你只关心文件,你可以说-type f-mindepth 1 使其不包含 ~/Linux/Old 路径本身到结果中。适用于任何文件名,包括那些包含嵌入换行符的文件名。

    一条评论指出 mv -t 选项可能是 GNU 扩展。对于没有它的系统

    find ~/Linux/Old -maxdepth 1 -mindepth 1 -not -name Tux.png \
        -exec mv '{}' ~/Linux/New \;
    

    【讨论】:

    • 赞成,因为它鼓励学习一个强大的工具,find。请注意,对于带有空格的文件,这将不起作用。考虑 "find -print0 | xargs -0" 或者放弃 xargs: "find [what you said] -exec mv -t {} ~/Linux/New \;"
    • 如果您的 mv 命令没有 -t 选项,则使用“find ... -exec mv {} Linux/New \;”或“查找 ... | xargs -I {} mv {} Linux/New”。 -t 选项似乎是一个 GNU 扩展,这对 Linux 来说很好,但在其他地方可能不行。
    • jhs,哦,我失败了。我以某种方式认为 xargs 在换行符处拆分,而不是在空格处拆分。看起来我把它和“读”弄混了:)我修好了
    • 非常感谢您的精彩提示!我打算选择某事,因为它针对问题。但是,稍后我可以感觉到您的命令的用处,因此我必须选择“查找和 xargs”方式。它只是岩石。谢谢:)
    • 复杂的方式。马西的答案更完整,更容易,因此更正确
    【解决方案6】:

    以下不是 100% 保证的方法,根本不应该尝试编写脚本。但有时它对于快速交互式 shell 使用来说已经足够了。一个文件文件 glob 像

    [abc]*
    

    (将匹配名称以 a、b 或 c 开头的所有文件)可以通过先插入“^”字符来否定,即

    [^abc]*
    

    我有时用它来匹配“lost+found”目录,例如:

    mv /mnt/usbdisk/[^l]* /home/user/stuff/.
    

    当然,如果还有其他以 l 开头的文件,我必须在之后处理这些文件。

    【讨论】:

      【解决方案7】:

      将以下内容放入您的 .bashrc

      shopt -s extglob
      

      它扩展了正则表达式。 然后,您可以移动除一个以外的所有文件

      mv !(fileOne) ~/path/newFolder
      

      与其他命令有关的例外情况

      请注意,在复制目录时,不能在线程 Why extglob except breaking except condition? 中注意到的名称中使用 forward-flash:

      cp -r !(Backups.backupdb) /home/masi/Documents/
      

      所以Backups.backupdb/ 在否定之前在这里是错误的,我不会在移动目录中使用它,因为有可能错误地使用它然后将 glob 与其他命令和可能的其他异常一起使用。

      【讨论】:

      • 这其实是正确的答案。我的完全错了;幸运的是,我在一个只有几个文件的文件夹中使用了它。以下是有关 Masi 显示的方法的更多信息:wiki.bash-hackers.org/syntax/pattern 转到“扩展模式语言”,您将找到有关此的更多信息。感谢@paul-whittaker 指出这个问题。
      • 这是一个旧答案,但仍然有效。我正在使用 Ubuntu 18,并且默认情况下似乎启用了 extglob(我没有购买它)。我使用以下命令将当前目录中的所有文件移动到也在该目录中的存档中,不包括任何其他存档文件夹:mv !(arc*) archive_190629b
      【解决方案8】:

      对于排除某些文件或目录的简单移动,我发现它更安全,更容易依赖。

      ls -1 | grep -v ^$EXCLUDE | xargs -I{} mv {} $TARGET
      

      【讨论】:

      • 这是 Busybox / ASH 的最佳解决方案
      • 这适用于我必须将除少数文件夹之外的所有文件移动到另一个目录的情况
      • -l 选项到ls 将在命令行中包含很多不相关的信息并导致 mv 命令失败。
      • @jdhao 这不是 L 是 1。
      • 即使在最简单的 Docker 容器上也能工作
      【解决方案9】:
      ls ~/Linux/Old/ | grep -v Tux.png | xargs -i {} mv ~/Linux/New/'
      

      【讨论】:

      • 这个命令好像少了一部分,在我的电脑上不起作用。 ls ~/Linux/Old/ | grep -v Tux.png | xargs -I{} mv {} ~/Linux/New/ 可以代替。
      【解决方案10】:

      我认为最简单的方法是使用反引号

      mv `ls -1 ~/Linux/Old/ | grep -v Tux.png` ~/Linux/New/
      

      编辑:

      将反斜杠与 ls 一起使用以防止将其与别名一起使用,即大多数情况下 ls 被别名为 ls --color。

      mv `\ls -1 ~/Linux/Old/ | grep -v Tux.png` ~/Linux/New/
      

      感谢@Arnold Roa

      【讨论】:

      • 你能解释一下为什么你在那里使用grep -v吗?
      • grep 中的 -v 选项排除了结果,就像获取除了 Tux.png 之外的所有内容
      • 这当然很直观,但上面的答案更好。例如,如果您正在编写脚本,这将要求您位于正确的目录中..
      • @nJGL 我们也可以在这里给出绝对路径,我使用主目录(~),因为问题有这个
      • @RohailAbbas 够公平的。 ✌️
      【解决方案11】:

      不用grep 也可以这样做:

      ls ~/Linux/Old/ -QI Tux.png | xargs -I{} mv ~/Linux/Old/{} ~/Linux/New/
      

      注意:-I 是一个大写字母 i,使ls 命令忽略后面列出的 Tux.png 文件。

      ls 的输出然后通过xargs 传送到mv,这允许使用 ls 的输出作为 mv 的源参数。

      ls -Q 只是引用 ls 列出的文件名。

      【讨论】:

      • 请您解释一下您发布的内容好吗?
      【解决方案12】:

      怎么样:

      mv $(echo * | sed s:Tux.png::g) ~/Linux/New/
      

      你必须在文件夹中。

      【讨论】:

        【解决方案13】:

        这可能更简单易记,而且对我有用。

        mv $(ls ~/folder | grep -v ~/folder/exclude.png) ~/destination

        【讨论】:

          【解决方案14】:

          将所有文件(不包括文件除外)移动到 except_file
          find -maxdepth 1 -mindepth 1 -not -name except_file -print0 |xargs -0 mv -t ./except_file
          例如(缓存是当前的,文件除外)
          find -maxdepth 1 -mindepth 1 -not -name cache -print0 |xargs -0 mv -t ./cache

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2019-06-14
            • 2018-07-01
            相关资源
            最近更新 更多