![将目录重组为层次结构](https://linux22.com/image/26190/%E5%B0%86%E7%9B%AE%E5%BD%95%E9%87%8D%E7%BB%84%E4%B8%BA%E5%B1%82%E6%AC%A1%E7%BB%93%E6%9E%84.png)
我有以下类型的文件夹结构,其中包含数千个文件夹。
文件夹名称本身具有不同的名称等
.test
.test.subfolder
.test.subfolder.subsubfolder
.folder
.folder.one
.folder.two
.folder.one.one
我需要实现的目标如下:我希望将文件夹重命名为例如从.test
到test
,然后移动.test.subfolder
以使该文件夹.subfolder
位于test
不带 的文件夹内.
,然后.test.subfolder.subsubfolder
使其subfolder
位于该文件夹内test
且subsubfolder
位于 内test/subfolder
。
由于有很多文件夹,因此这需要递归。请记住,文件夹中的文件仍应保持完整。
这是可能吗?
答案1
这个 bash 脚本可以满足您的需要:
#!/bin/bash
for dir in .*/ ; do
[[ $dir == ./ || $dir == ../ ]] && continue # Skip the special dirs
new=${dir#.} # Remove the dot at the beginning
new=./${new//.//} # Replace dots with slashes, prepend ./
new=${new%/} # Remove the trainling slash
mkdir -p ${new%/*} # Create the parent dir
mv "$dir" "$new" # Move the dir to destination
done
答案2
是的,这很有可能。你需要做的是你需要读取路径中的所有文件名并考虑空格、点等如果你想有效地做到这一点,你可以使用这个线程:如何以优雅的方式对子文件夹中具有特定扩展名的所有文件执行操作?
现在,一旦您读取了路径名中的文件,您就必须制定规则。
例如,让我们考虑这个结构:
.test
.test.subfolder
.test.subfolder.subsubfolder
您要做的是计算每个文件名中单词 sub 的出现次数。因此,如果计数为:0,则它是父文件夹,如果计数:1,则它是第一级子文件夹,如果计数:3-->它是第二级子文件夹,依此类推(级别是从结构由您提供)
因此,可能的伪代码如下所示:
if(filename contains(".test"))
{
searchCount("sub");
if(count ==0)
parent();
else if(count ==1)
1stLevelChild();//and so on
}
现在,根据您得到的结果,您只需使用移动命令将文件移动到适当的文件夹中即可。
答案3
这在 zsh 中非常简单,感谢zmv
。由于通配符.*
按字典顺序扩展文件名,因此将始终在其子目录之前重命名要成为父目录的目录,因此,eg在重命名test
时已经存在。.test.subfolder
zmv '.(*)' "${1//./\/}"