Passe por todas as subpastas, procure uma pasta e execute o script

2

Eu tenho um diretório que contém subpastas de várias profundidades. Eu quero passar por todos eles, verificar se eles contêm uma pasta com um certo nome, e se esse diretório existir, execute um script (vamos chamar esse script foo.sh para evitar confusão).

foo.sh deve ser executado na pasta atual se encontrar a pasta de destino. Exemplo:

/A
  /subA-1
  /subA-2
    /target
  /subA-3
    /sub-subA-3
       /target

O comando / script que estou procurando será executado a partir de /A e passará por todas as subpastas procurando uma pasta com o nome target . Ao inserir /subA-2 , esta condição é satisfeita e o foo.sh é executado em /subA-2 . Mesmo para /sub-subA-3 , mas não /subA-3 .

foo.sh não precisa de nenhuma entrada, só precisa ser executado na pasta que contém /target .

    
por snurden 01.03.2016 / 13:48

4 respostas

4

É tão simples assim:

find A -type d -name target -execdir foo.sh \;

Da página do manual:

-execdir command ;

Like -exec, but the specified command is run from the subdirectory containing the matched file.

Exemplo:

Crie e imprima a estrutura de diretórios da pergunta:

/tmp$ mkdir A; cd A
/tmp/A$ mkdir -p subA-1 subA-2/target subA-3/sub-subA-3/target
/tmp/A$ find .
.
./subA-2
./subA-2/target
./subA-3
./subA-3/sub-subA-3
./subA-3/sub-subA-3/target
./subA-1

Agora, execute o comando, substituindo pwd por foo.sh para mostrar o que está acontecendo:

/tmp/A$ find . -type d -name target -execdir pwd \;
/tmp/A/subA-2
/tmp/A/subA-3/sub-subA-3
    
por 01.03.2016 / 16:24
1

Com zsh:

cd /A && for dir (**/target(/N:h) (cd -- $dir && foo.sh)
    
por 01.03.2016 / 15:19
1

A maneira mais simples seria usar find para localizar todos os diretórios e depois modificar seu script para verificar se existe um diretório com o nome correto ( foobar , por exemplo):

#!/bin/bash

targetDir="$@"   ## The directory to run the script on
dirName="target" ## Change this to whatever the "target" is
cd "$trargetDir"
## Exit if the $targetDir doesn't have a directory with 
## the name you're looking for
[ -d "$targetDir"/"$dirName" ] || exit

## If it does, cd into the $targetDir and continue the script
cd "$targetDir"

### The rest of the script goes here
...

Agora, você pode executar um comando find e executá-lo em cada diretório encontrado:

find /target -type d -exec /path/to/script.sh "{}" \; 

Você também pode fazer a coisa toda com find , mas, pessoalmente, acho a solução acima mais limpa. Cabe a você, no entanto. Aqui está uma maneira:

pwd="$PWD"; find . -type d -name foobar -printf '%h
#!/bin/bash

targetDir="$@"   ## The directory to run the script on
dirName="target" ## Change this to whatever the "target" is
cd "$trargetDir"
## Exit if the $targetDir doesn't have a directory with 
## the name you're looking for
[ -d "$targetDir"/"$dirName" ] || exit

## If it does, cd into the $targetDir and continue the script
cd "$targetDir"

### The rest of the script goes here
...
' | while IFS= read -d '' dir; do cd "$dir" && foo.sh; cd "$pwd"; done
    
por 01.03.2016 / 14:27
-1

Use o comando find:

man find tem alguns exemplos: como

find /tmp -name core -type f -print | xargs /bin/rm -f

find . -type f -exec file '{}' \;
    
por 01.03.2016 / 14:21