我有以下文件结构:
- /主页/数据/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
变量只能通过前缀来识别和扩展
$
。如果循环定义了变量“i”,则需要使用$i
每当你想要它的值时:for i in */; do cd $i/*/
“当前目录”是整个进程的,不会在每次循环迭代时自动重置。您需要在之后手动返回父目录:
cd $i/*/; mv * ../; cd ../../
或者使用“子 shell”来限制目录更改范围:
(cd $i/*/; mv * ../)
您没有进行任何错误检查。如果
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
改进:您可以将子目录通配符移动到
mv
,即使有多个子目录也可以正常工作:cd $i/ || exit mv */* . cd ../
改进:你完全不需要做任何事就可以做到这一点
cd
:mv $i/*/* $i/