扁平化目录层次结构在新目录名称中保留目录名称

aks*_*618 7 bash zsh directory shell-script rename

我基本上想从这个开始:

.
??? Alan Walker
?   ??? Different World
?   ?   ??? 01 Intro.mp3
?   ?   ??? 02 Lost Control.mp3
?   ?   ??? cover.jpg
?   ??? Same World
?       ??? 01 Intro.mp3
?       ??? 02 Found Control.mp3
??? Aurora
?   ??? Infections Of A Different Kind Step 1
?       ??? 01 Queendom.lrc
?       ??? 02 Forgotten Love.lrc
?       ??? 03 Gentle Earthquakes.mp3
??? Guns N' Roses
    ??? Use Your Illusion I
        ??? 01 Right Next Door To Hell.lrc
        ??? 01 Right Next Door To Hell.mp3
        ??? 02 Dust N' Bones.lrc
        ??? 02 Dust N' Bones.mp3
Run Code Online (Sandbox Code Playgroud)

对此:

.
??? Alan Walker - Different World
?   ??? 01 Intro.mp3
?   ??? 02 Lost Control.mp3
?   ??? cover.jpg
??? Alan Walker - Same World
?   ??? 01 Intro.mp3
?   ??? 02 Found Control.mp3
??? Aurora - Infections Of A Different Kind Step 1
?   ??? 01 Queendom.lrc
?   ??? 02 Forgotten Love.lrc
?   ??? 03 Gentle Earthquakes.mp3
??? Guns N' Roses - Use Your Illusion I
    ??? 01 Right Next Door To Hell.lrc
    ??? 01 Right Next Door To Hell.mp3
    ??? 02 Dust N' Bones.lrc
    ??? 02 Dust N' Bones.mp3
Run Code Online (Sandbox Code Playgroud)

我能找到的现有解决方案都没有包括重命名目录本身。能够用 zmv 做到这一点会很棒,但我不知道该怎么做。

Kus*_*nda 12

也许像这样的东西?

#!/bin/sh

for topdir in */; do
    topdir_name=$( basename "$topdir" )

    for subdir in "$topdir"/*/; do
        subdir_name=$( basename "$subdir" )

        newdir="$topdir_name - $subdir_name"
        if mkdir "$newdir"; then
            mv "$subdir"/* "$newdir"
            rmdir "$subdir"
        fi
    done

    rmdir "$topdir"
done
Run Code Online (Sandbox Code Playgroud)

这将遍历当前目录中的所有顶级目录(乐队名称)。对于每个这样的目录,它遍历其子目录(专辑名称)。对于每对乐队名称和专辑名称,都会创建一个新目录并将子目录中的文件移动到该目录中。专辑子目录在处理完毕后将被删除,原始乐队顶级目录也是如此。

rmdir如果任何目录包含隐藏文件名或任何新目录未能创建,调用将失败。

这是完全未经测试的代码。在文件的备份副本上运行它。

  • 将 ot 放入脚本中,然后 -boom- 它变成单行。 (10认同)

Gil*_*il' 9

Zsh

未经测试:

zmv -Q '(*)/(*)(/)' '$1 - $2'
rmdir -- *(/^F)
Run Code Online (Sandbox Code Playgroud)

第二行删除所有空目录,即使是那些以前没有文件的目录。可以使用自定义mv包装器来解决这个问题,该包装器记录它从哪些目录中移动内容。

请注意,这会遍历指向当前目录中目录的符号链接。

Linux 重命名实用程序

未经测试。

rename / ' - ' */*/
rmdir -- */ 2>/dev/null
Run Code Online (Sandbox Code Playgroud)

请注意,这会遍历指向当前目录及其子目录中目录的符号链接。第二行删除所有空目录,即使是那些以前没有文件的目录。

Perl 重命名脚本

未经测试。

prename 's~/~ - ~' */*/
rmdir -- */ 2>/dev/null
Run Code Online (Sandbox Code Playgroud)

请注意,这会遍历指向当前目录及其子目录中目录的符号链接。第二行删除所有空目录,即使是那些以前没有文件的目录。

这是一种更复杂的方法,它只删除它从中重命名的目录。再次,未经测试。

prename 's~([^/]+)/~$1 - ~ and ++$d{$1}; END {map {rmdir} keys %d}' */*/
Run Code Online (Sandbox Code Playgroud)