Eu tenho o mesmo problema que foi perguntado na pergunta Renomear arquivos de música com extensões de arquivo ausentes e achei o roteiro fornecido pelo @Gilles muito educativo, mas infelizmente não funcionou como eu esperava. O que eu procurava era um script que adicionasse uma extensão de arquivo a todos os arquivos de música sem extensão em todos os subdiretórios, em todos os níveis, abaixo de "/caminho/para/music/diretório/". O parâmetro de linha de comando sugerido
/path/to/music/directory/{**/,}*
faz com que o script passe por todos os arquivos nos subdiretórios um nível abaixo de "/path/to/music/directory/", mas não em níveis abaixo disso. Qual parâmetro de linha de comando devo usar para percorrer todos os arquivos em todos os níveis abaixo de "directory/" ?
Gostaria também de receber uma indicação da documentação para o
{**/,}*
papel.
Aliás, para aqueles interessados na resposta original. Descobri que o script funciona melhor depois que mudei a linha
file -i "$@" |
para
file --mime-type "$@" |
(Se eu tivesse o nível de privilégio, teria dado isso como comentário na resposta original)
Responder1
Acho que você só precisa ativar a globstar
opção bash, pois ela não está ativa por padrão noUbuntu, conforme explicado a seguir.
A expressão /path/to/music/directory/{**/,}*
contém duas construções de expansão: tem uma expansão de chaves e a seguir uma expansão de nome de caminho.
Expansão de cinta
A expansão do suporte é melhor explicada com um exemplo:
$ printf '%s\n' before-{a,bb,1,22}-after
before-a-after
before-bb-after
before-1-after
before-22-after
(Usei, aqui e a seguir, o comando printf '%s\n' item1 item2 etc..
que é parecido echo
, mas imprime cada elemento em uma nova linha)
Você vê que cada elemento separado por vírgula entre colchetes resulta em um elemento expandido.
O exemplo original, contendo entre colchetes os elementos **/
e um elemento vazio, se expande para
$ printf '%s\n' /path/to/music/directory/{**/,}*
/path/to/music/directory/**/*
/path/to/music/directory/*
estrela glob
Voltemos agora para o bash glob **
, que é mencionado duas vezes nopágina de manual do bash, ambos em relação à opção shell globstar
, e o significado é o seguinte:
o padrão ** usado em um contexto de expansão de nome de caminho corresponderá a arquivos e zero ou mais diretórios e subdiretórios.
Esta opção de shell não éativopor padrão no Ubuntu:
$ shopt globstar
globstar off
Você pode ativá-lo com
shopt -s globstar
(use shopt -u globstar
para desativá-lo).
Se tivermos a seguinte estrutura de diretórios:
$ 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
poderíamos ter as seguintes expansões:
$ 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
então você pode ver que **
é capaz de expandir para mais de um elemento pathname.
Responder2
eu faria algo assim
#! /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
e então invocar o script via./my_script <directory>