如何使用 bash 将多个目录中的所有文件移动到其父目录

如何使用 bash 将多个目录中的所有文件移动到其父目录

我有以下文件结构:

  • /主页/数据/C01/目录_wwe_346/file1.txt pic.jpg 随机.sh
  • /主页/数据/C02/目录_wwe_644/file1.txt pic.jpg 随机.sh
  • /主页/数据/C03/目录_wwe_324/file1.txt pic.jpg 随机.sh

我希望他们是这样的:

  • 主页/数据/C01/file1.txt pic.jpg 随机.sh
  • 主页/数据/C02/file1.txt pic.jpg 随机.sh
  • 主页/数据/C03/file1.txt pic.jpg 随机.sh

它基本上是将多个文件向上移动一个目录,我尝试过这个脚本但没有成功:

#!/bin/bash for i in */ do cd i/*/ mv * ../ done


发布这篇文章后(但在阅读下面的 Grawity 回应之前),我意识到我没有使用正确的变量扩展,并运行了这个:

#!/bin/bash for i in */ do cd ${i}*wwe* mv * ../ done

该脚本正在将所有子目录移动到数据文件夹,因此我最终得到如下结果:

  • //C01/目录_wwe_346/file1.txt pic.jpg 随机.sh
  • //C02/目录_wwe_644/file1.txt pic.jpg 随机.sh
  • //C03/目录_wwe_324/file1.txt pic.jpg 随机.sh

    我究竟做错了什么?


PS。我编辑了帖子,以便它能揭示我经历的过程,并且回复对可能从这些回复中受益的新来者来说更有意义。谢谢grawity,我学到了新东西。我一周前才开始学习bash,我感觉自己正在进步。

答案1

  1. 变量只能通过前缀来识别和扩展$。如果循环定义了变量“i”,则需要使用$i每当你想要它的值时:

    for i in */; do
        cd $i/*/
    
  2. “当前目录”是整个进程的,不会在每次循环迭代时自动重置。您需要在之后手动返回父目录:

    cd $i/*/; mv * ../; cd ../../
    

    或者使用“子 shell”来限制目录更改范围:

    (cd $i/*/; mv * ../)
    
  3. 您没有进行任何错误检查。如果cd失败,后续操作mv可能会产生令人不快的结果。要么使用连接命令&&,要么进行相反的检查并使用|| exit(或|| break),以最佳方式为准:

    for i in */; do
        cd $i/*/ && {
            mv * ../;
            cd ../../
        }
    done
    
    for i in */; do
        cd $i/*/ || exit
        mv * ../
        cd ../../
    done
    
    for i in */; do
        (cd $i/*/ && mv * ../)
    done
    
  4. 改进:您可以将子目录通配符移动到mv,即使有多个子目录也可以正常工作:

    cd $i/ || exit
    mv */* .
    cd ../
    
  5. 改进:你完全不需要做任何事就可以做到这一点cd

    mv $i/*/* $i/
    

相关内容