Listar elementos com espaços em zsh

10

Eu tenho estudado o script zsh por todas as duas horas neste momento e acertei uma parede. Eu quero passar por uma lista de arquivos que podem ter espaços neles. Estou aberto a abordagens completamente diferentes do exemplo a seguir, desde que sejam zsh, já que zsh é o que estou estudando, não a tarefa que estou tentando roteirizar.

files=('ls')
for f in $files; do
    print $f
done

Eu obviamente não estou apenas recriando ls , apenas quero que $f capture o nome do arquivo inteiro em cada iteração do loop.

    
por Felix 11.01.2012 / 16:01

2 respostas

12

Primeiro, suponho que o uso de ls seja apenas um exemplo. Você não pode analisar a saída de ls em qualquer shell, porque é ambíguo. Leia Por que você não deve analisar a saída de ls (1) se isso for novidade para você. Em qualquer shell, para obter uma lista de arquivos, use curingas, por exemplo. files=(*) .

No zsh, como em outros shells, o resultado da substituição do comando é dividido em palavras em caracteres de espaço em branco (mais precisamente, de acordo com o valor de IFS ). (Ao contrário de outros shells, o resultado da substituição de comandos não está sujeito a globbing em zsh.) Portanto, se a saída do comando ls for

hello world
wibble

, em seguida, files=($(ls)) define a matriz files para conter 3 elementos: hello , world e wibble .

Se a substituição do comando estiver entre aspas duplas, nenhuma divisão será executada. Você pode realizar uma divisão personalizada com sinalizadores de expansão de parâmetro . Use o @ flag para indicar que o resultado da divisão deve ser uma matriz (estranhamente, você precisa manter a expansão entre aspas duplas, ou seja, "${(@)…}" , mesmo que a sequência de aspas duplas seja expandida para várias palavras) . Para divisão, use o sinalizador s , por ex. "${(@s:,:)…}" para dividir com vírgulas; o sinalizador f se divide somente em novas linhas.

files=("${(@f)$(ls)}")

Observe que a maneira correta de iterar em uma matriz em geral é for f in $files[@] , pois $files retira os elementos vazios (aqui, não importa, porque os elementos não estarão vazios).

print $f interpreta $f como um switch se começar com - e expande as barras invertidas em $f . Use print -r -- $f ou print -rn -- $f se você não quiser adicionar uma nova linha após a string.

    
por 11.01.2012 / 18:25
2

No zsh você pode usar a expansão do shell que não executa a divisão de palavras por padrão. Experimente

for f in /path/to/files/*; do
    print ${f}
done
    
por 11.01.2012 / 16:58