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

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

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

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

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

也希望有一个指向文档的指针

{**/,}* 

部分。

顺便说一句,对于那些对原始答案感兴趣的人。我发现在我更改了以下行之后,脚本运行得更好

file -i "$@" |

file --mime-type "$@" | 

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

答案1

我认为你只需要激活 bashglobstar选项,因为它默认不处于活动状态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/*

全球星

现在转向 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

因此您可以看到它**能够扩展到多个路径名元素。

答案2

我会做这样的事情

#! /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 <directory>

相关内容