我的音乐库很乱。
我尝试创建这个结构:
/音乐
/音乐/艺术家/专辑/
由于某种原因,我有几个具有这种结构的艺术家。
/音乐
/音乐/艺术家/艺术家/
/音乐/艺术家/艺术家/专辑/
我如何才能从“/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
之前的mv
和rmdir
删除。
请注意,命令将包含双重/
,例如,artist//artist//album
但这不应该是个问题。
答案3
使用 GNU find
:
find /music -type d -execdir test -d {}/{} \; -print
对于 类型的每个文件,目录都test
将运行。诀窍在于-execdir
它与 的不同之处-exec
:对于名为 的目录something
,test
将在其父目录并将{}
扩展为./something
。实际上,实际的内部命令将是test -d ./something/./something
,相当于test -d something/something
。然后我们使用这样一个事实:(-execdir … \;
像-exec … \;
)不仅是一个动作,它是一个测试,当且仅当它运行的退出状态为 0 时,它才会成功。test -d
检查给定的路径名是否是目录的名称,它通过其退出状态报告成功。
这种方式-print
只会对包含同名目录的目录进行评估(几乎只会见下文)。
笔记:
test -d
对于目录的符号链接,也会成功。您可以! -execdir test -L {}/{} \;
在 之前添加 ( ) 以忽略是符号链接的-print
情况。something/something
一般来说,请记住,
{}
扩展为考虑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
那么就没有问题。find
当处理每对中较上层(较接近/
)的目录something/something
而不是较下层目录时,检测成功。这会产生以下后果:我们的命令将打印类似的路径
/music/foo/bar/something
(而不是/music/foo/bar/something/something
)对于
-mindepth
或-maxdepth
(如果您决定使用它们),上层目录的深度很重要。如果您想要自动对其中一个目录执行某些操作:
{}
通过在-exec
或之后传递与上面的操作一起工作-execdir
;- 但解决较低问题的最简单方法是像我们一样使用
{}/{}
after-execdir
;一般来说,这将不是工作后-exec
。