Que linha de comando para atravessar de forma confiável vários níveis de diretório

0

Eu tenho o mesmo problema que foi perguntado em questão Renomear arquivos de música com extensões de arquivo ausentes e achei o script fornecido pelo @Gilles muito educativo, mas infelizmente não funcionou como eu esperava. O que eu estava procurando 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 "/ path / to / music / directory /". O parâmetro de linha de comando sugerido

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

faz o script passar 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 "diretório /"?

Também apreciaria um apontador para documentação para o

{**/,}* 

parte.

BTW, para os interessados na resposta original. Eu achei que o script funciona melhor depois que eu mudei a linha

file -i "$@" |

para

file --mime-type "$@" | 

(Se eu tivesse o nível de privilégio, eu teria dado isso como um comentário na resposta original)

    
por Andy 31.07.2011 / 21:00

2 respostas

1

Eu acho que você tem apenas que ativar a opção bash globstar , porque ela não está ativa por padrão no Ubuntu , como explicado a seguir.

A expressão /path/to/music/directory/{**/,}* contém duas construções de expansão: possui uma expansão de chave e, em seguida, uma expansão de nome de caminho.

Expansão de órtese

A expansão de chave é 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

(Eu usei, aqui e a seguir, o comando printf '%s\n' item1 item2 etc.. que é como echo , mas imprime cada elemento em uma nova linha)

Você vê que cada elemento separado por vírgula nas chaves resulta em um elemento expandido.

O exemplo original, contendo entre chaves os elementos **/ e um elemento vazio, expande para

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

Globstar

Mude agora para o bash glob ** , que é mencionado duas vezes no Página de manual do bash , ambos em relação à opção de shell globstar , e o significado é o seguinte:

% bl0ck_qu0te%

Esta opção de shell não está ativa por 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ório:

$ 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

para que você possa ver que ** é capaz de se expandir para mais de um elemento de nome de caminho.

    
por enzotib 31.07.2011 / 22:09
1

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 invoque o script via ./my_script <directory>

    
por arrange 31.07.2011 / 22:06