什么命令行可靠地遍历多个目录级别

我遇到的问题与问题重命名音乐文件丢失的文件扩展名相同 ,我发现@Gilles提供的脚本非常有教育意义,但不幸的是它没有按照我的预期工作。 我正在寻找的是一个脚本,可以在所有级别的“/ path / to / music / directory /”下面的所有子目录中为所有音乐文件添加文件扩展名而不扩展。 建议的命令行参数

/path/to/music/directory/{**/,}* 

使脚本遍历“/ path / to / music / directory /”下一级子目录中的所有文件,但不低于该级别。 我应该使用什么命令行参数遍历“directory /”下面所有级别的所有文件?

也会欣赏指向文档的指针

 {**/,}* 

部分。

BTW,对于那些对原始答案感兴趣的人。 我发现改变线后脚本效果更好

 file -i "$@" | 

 file --mime-type "$@" | 

(如果我有特权级别,我会在原答案中将此作为评论)

我认为你只需激活bash globstar选项,因为它在Ubuntu中默认不活动,如下所述。

表达式/path/to/music/directory/{**/,}*包含两个扩展构造:具有大括号扩展,接下来是路径名扩展。

支撑扩张

通过一个例子可以最好地解释支撑扩展:

 $ printf '%s\n' before-{a,bb,1,22}-after before-a-after before-bb-after before-1-after before-22-after 

(我在这里和下面使用了命令printf '%s\n' item1 item2 etc..就像echo一样,但在新行上打印每个元素)

您会看到大括号中的每个逗号分隔元素都会生成一个展开的元素。

包含大括号元素**/和空元素的原始示例扩展为

 $ printf '%s\n' /path/to/music/directory/{**/,}* /path/to/music/directory/**/* /path/to/music/directory/* 

Globstar

现在转到bash glob ** ,在bash手册页中提到两次,两者都与shell选项globstar ,其含义如下:

路径名扩展上下文中使用的模式**将匹配文件和零个或多个目录和子目录。

默认情况下,此shell选项在Ubuntu中不活动

 $ shopt globstar globstar off 

你可以激活它

 shopt -s globstar 

(使用shopt -u globstar来停用它)。

如果我们有以下目录结构:

 $ find first/ | sort first/ first/aaa first/second first/second/bbb01 first/second/bbb02 first/second/third first/second/third/ccc1 first/second/third/ccc2 first/second/third/ccc3 

我们可以进行以下扩展:

 $ printf '%s\n' first/**/a* first/aaa $ printf '%s\n' first/**/b* first/second/bbb01 first/second/bbb02 $ printf '%s\n' first/**/c* first/second/third/ccc1 first/second/third/ccc2 first/second/third/ccc3 

所以你可以看到**能够扩展到多个路径名元素。

我会做这样的事情

 #! /bin/bash [[ -d "$1" ]] || { echo "$1 not a directory, exiting..."; exit 1; } find "$1" -type f | while read F; do # do what you want with the "$F" done exit 0 

然后通过./my_script 调用脚本