如何列出包含同名子目录的所有目录?

如何列出包含同名子目录的所有目录?

我的音乐库很乱。

我尝试创建这个结构:

/音乐

/音乐/艺术家/专辑/

由于某种原因,我有几个具有这种结构的艺术家。

/音乐

/音乐/艺术家/艺术家/

/音乐/艺术家/艺术家/专辑/

我如何才能从“/mymusic”中找到包含同名子目录“/mymusic/artist/artist”的每个艺术家目录,以便我可以手动修复结构。

比你。

答案1

你可以尝试一个find命令,这个例子应该扫描所有的音乐内容:

find /music -mindepth 1 -print

添加awk命令来过滤路径的每个组件(以“/”作为分隔符)并检查最后一个和倒数第二个组件匹配的位置,将告诉您何时重复了目录和子目录名称:

find /music -mindepth 1 -print | awk -F"/" '{ if ($NF == $(NF-1)) { print }}'

答案2

下面的命令循环遍历所有子目录名称,检查是否存在同名的嵌套子目录,并显示将内容向上移动一个目录并重新移动嵌套子目录的命令。

cd /music
for i in */
do
    if [ -d "$i/$i" ]
    then
       echo mv "$i/$i"/* "$i"/.
       echo rmdir "$i/$i"
    fi
done

如果这是您所需要的,请重复该命令并将echo之前的mvrmdir删除。

请注意,命令将包含双重/,例如,artist//artist//album但这不应该是个问题。

答案3

使用 GNU find

find /music -type d -execdir test -d {}/{} \; -print

对于 类型的每个文件,目录都test将运行。诀窍在于-execdir它与 的不同之处-exec:对于名为 的目录somethingtest将在其父目录并将{}扩展为./something。实际上,实际的内部命令将是test -d ./something/./something,相当于test -d something/something。然后我们使用这样一个事实:(-execdir … \;-exec … \;)不仅是一个动作,它是一个测试,当且仅当它运行的退出状态为 0 时,它才会成功。test -d检查给定的路径名​​是否是目录的名称,它通过其退出状态报告成功。

这种方式-print只会对包含同名目录的目录进行评估(几乎只会见下文)。

笔记:

  1. test -d对于目录的符号链接,也会成功。您可以! -execdir test -L {}/{} \;在 之前添加 ( ) 以忽略是符号链接的-print情况。something/something

  2. 一般来说,请记住,{}扩展为考虑find当前处理文件的路径名,而不一定是命令realpath …将要打印的内容。类似地,-name测试find考虑名称的内容,而不一定是basename "$(realpath …)"将要打印的内容。例如,如果起点是,/music那么在某个时候我们的命令将./music/./music在内部进行测试/music/..,因此实际上/music/music可能是也可能不是现有目录,并且测试是结论性的,这很好。但是:

    • 如果 (或 a) 起点是.(或例如/music/.!),那么它将被报告,因为test -d将测试./././.哪个是目录肯定 (无论 的工作目录test),因此测试不是结论性的。! -name .是一个“修复”此问题的测试,即它无条件排除.。但现在我们可能会错过一个目录:如果当前工作目录是/music并且/music/music存在,我们将不会检测到它。

      一般情况下,将.用作起点find是很常见的。在我们的例子中,如果您需要从 开始.,请考虑find "$PWD" …

    • 类似地,如果 (或 a) 起点是..(或例如/music/artist/..),那么它将被报告,因为test -d将测试./.././..哪个是肯定的目录(无论 的工作目录test)。! -name ..是一个“修复”此问题的测试,但我们再次可能会错过一个特定目录。一般来说,将..作为起点传递到find并不常见,但仍然有可能。

    如果起点是/music那么就没有问题。

  3. find当处理每对中较上层(较接近/)的目录something/something而不是较下层目录时,检测成功。这会产生以下后果:

    • 我们的命令将打印类似的路径/music/foo/bar/something(而不是/music/foo/bar/something/something

    • 对于-mindepth-maxdepth(如果您决定使用它们),上层目录的深度很重要。

    • 如果您想要自动对其中一个目录执行某些操作:

      • {}通过在-exec或之后传递与上面的操作一起工作-execdir
      • 但解决较低问题的最简单方法是像我们一样使用{}/{}after -execdir;一般来说,这将不是工作后-exec

相关内容