Como posso fazer manipulação de subdiretórios no shell?

0

Por exemplo, executando um comando no n-número de subdiretórios classificados, onde n é uma entrada. Ou Como posso executar um loop for em um intervalo de subdiretórios onde posso dar esse intervalo como uma entrada? Como o seguinte, exceto como posso definir o intervalo aqui?

for d in ["sd1"-"sd2"] do ( cd "$d" && do stuff ) done
    
por DarkMatter 23.08.2017 / 09:55

4 respostas

2

Use a expansão de contraventamento se você tiver um shell que suporte:

for d in sd{1..2}; do
    ( cd "$d" && dostuff )
done

Com zsh , ksh93 ou yash -o braceexpand (mas não bash ), você pode fazer

n=4
for d in sd{1..$n}; do
    ( cd "$d" && dostuff )
done

Pergunta relacionada: Posso usar variáveis dentro da expansão {}? sem 'eval'?

Uma variação disso seria

for (( i=1; i<=n; ++i )); do
  str="sd$i"
  ( cd ... )
done

Este é o loop for do estilo C suportado por bash e outras shells (ainda uma extensão para o padrão POSIX).

    
por 23.08.2017 / 09:57
1

Outra solução possível é usar o comando seq (onde estiver disponível)

for i in 'seq -f "sd%03.0f" 111 121'
do
( cd "$i" && do stuff )
done
    
por 23.08.2017 / 10:03
1

Com zsh , você pode fazer:

for d (sd<1-10>(Nn-/)) (cd $d && dostuff)
  • <1-10> é um operador glob que combina números inteiros decimais entre 1 e 10. Ele corresponderá a 1 , 001 ... Você pode torná-lo <-> para corresponder a qualquer número inteiro decimal positivo.
  • (Nn-/) é um qualificador glob.
    • N para não falhar se não houver correspondência
    • n para ordenar os elementos numericamente (assim, sd10 vem depois de sd2 )
    • -/ para incluir apenas arquivos do tipo diretório (após a resolução do link simbólico).

Se você quisesse listar diretórios entre duas datas, onde a data é codificada no nome do diretório (como sd2017-08-01 ):

for d (sd<->-<->-<->(Nne{'
  [[ ! $REPLY < sd2015-06-06 && ! $REPLY > sd2017-08-09 ]]'}-/))
  (cd $d && dostuff)
    
por 23.08.2017 / 10:24
0

As expansões globais são classificadas, o que significa que você pode fazer algo como:

state=0
for d in *; do
   case $d in "sd1") state=1;; "sd2") break;; esac
   if [ 1 -eq "$state" ]; then
      ( cd "$d" && dostuff )
   fi
done

Estou assumindo aqui que sd1 e sd2 não são exemplos reais e que o intervalo não pode ser descrito com intervalos numéricos triviais. Se eles pudessem, eu usaria .stackexchange.com / a / 387821/23692 "> solução .

As expansões do Brace são muito legais, mas infelizmente, muitas shells do POSIX não as possuem, já que elas não são um requisito do POSIX.

    
por 23.08.2017 / 10:11