Por que a saída desse comando de eco está sendo executada em várias linhas?

1

Eu tenho um diretório de fotos cujos nomes são a hora e a data em que a foto foi tirada. Por exemplo:

~$ ls directory -1
2003-09-15 03.30.33.jpg
2004-05-04 12.45.28.jpg
2004-05-04 12.45.51.jpg

No entanto, se eu executar este comando como parte de um loop for e ecoar a saída, os espaços nos nomes de arquivos serão tratados como novas linhas:

~$ for pic in 'ls directory -1' ; do echo  "$pic"; done
2003-09-15
03.30.33.jpg
2004-05-04
12.45.28.jpg
2004-05-04
12.45.51.jpg

Por que isso está acontecendo e como posso pará-lo?

    
por Darren 08.06.2017 / 17:03

3 respostas

4

Como as outras respostas são íntimas, o problema é como o loop está processando a saída do comando ls . Quando uma string é usada no loop for , a string é dividida em palavras diferentes (com base no valor de IFS como Darren diz) e sujeita a globbing e similares. Isso significa que você está passando uma string que é dividida pela linha e pelos espaços dentro da linha, então cada uma dessas palavras é definida em pic .

A sugestão de Kamil resolve este problema porque você deixa o glob expandir para todos os nomes de arquivos diretamente, e todo o nome do arquivo é então atribuído a pic .

Essa divisão de palavras acontecerá em qualquer lugar em que você usar a variável pic mais tarde, portanto, se você não quiser que isso aconteça, certifique-se de colocar aspas duplas em torno dela. Por exemplo,

for pic in *; do
    printf '%s\n' "$pic"
done

para imprimir cada um dos nomes, um por linha.

    
por 08.06.2017 / 17:39
3

No seu caso, globbing simples pode ser suficiente:

for pic in * ; do …

Dessa forma, você também evita analisar ls , que em geral é não é uma boa ideia .

    
por 08.06.2017 / 17:19
1

Pergunta respondida aqui . A resposta curta é executar este comando:

IFS=$(echo -en "\t\n
IFS=$(echo -en "\t\n%pre%")
")
    
por 08.06.2017 / 17:13