Renomeia um arquivo contendo dinamicamente espaços [duplicado]

1

Eu quero renomear um arquivo dinamicamente com base em dados que contenham espaços

Name="Abc DEF"
Name1="GHI JKL"

mv /sample/pdf/noriginalName.pdf /sample/outputPdf/${NAME}${Name1}".pdf"

Mas isso me causa um erro porque encontra espaço entre eles.

Como posso fazer isso?

    
por Rahul 14.08.2014 / 09:53

2 respostas

4

Você deve citar todo o nome do arquivo:

mv /sample/pdf/noriginalName.pdf "/sample/outputPdf/${NAME}${Name1}.pdf"

Usando aspas duplas, evite bash e outros shells semelhantes a Bourne (exceto zsh ) executar Divisão de campos depois que sua variável for expandida.

    
por 14.08.2014 / 09:55
4

Não se preocupe, você não é o primeiro e não será o último a ser mordido por isso. É a pergunta mais freqüente sobre shells, e é responsável pela maioria dos bugs e vulnerabilidades de segurança encontrados nos shell scripts. Isso é devido a uma má escolha de design do shell Bourne e do shell Korn no histórico Unix anterior.

No shell Bourne e na maioria de seus descendentes (ksh, ash, pdksh, mksh, bash, traço, yash ...), deixar uma variável sem aspas é o operador split + glob.

Melhor demonstrado com:

$ var='*.txt,.*'
$ IFS=',' # default is space tab and newline
$ printf '<%s>\n' $var
<file.txt>
<.>
<..>

O shell dividiu $var em , caracteres e expandiu cada uma das palavras resultantes (que, nesse caso, contêm caracteres curinga) na lista de arquivos que correspondem ao padrão correspondente.

É por isso que, em shells parecidos com Bourne (exceto zsh ), você deve sempre citar suas variáveis (a menos que você queira o split e / ou glob )

$ printf '<%s>\n' "$var"
<*.txt:.*>

Então, no seu caso:

mv /sample/pdf/noriginalName.pdf "/sample/outputPdf/${NAME}${Name1}.pdf"

ou:

mv /sample/pdf/noriginalName.pdf /sample/outputPdf/"${NAME}${Name1}".pdf

(onde você coloca as aspas não importa, desde que as variáveis sejam citadas).

Você pode desativar a divisão apenas com:

IFS=

E você pode desativar o globbing apenas com:

set -f # affects all globbing, not only the one done upon variable expansion.

Com:

IFS=; set -f

Você obtém o mesmo comportamento de zsh para expansão de parâmetro, sem globbing, sem divisão. Você ainda precisa citar sua variável, no entanto, em

cmd "$var"

Se você quiser que cmd seja passado a um argumento vazio quando $var estiver vazio ou não definido (ao contrário do argumento não ). Um exemplo típico é [ -n "$var" ] , se você não citar $var , o teste sempre será verdadeiro, pois quando $var estiver vazio, isso será resolvido como [ -n ] em vez de [ -n '' ] .

Em zsh , globbing e divisão não são feitos implicitamente na expansão da variável (exceto no modo de emulação sh ou ksh ). Você precisa solicitá-lo explicitamente usando operadores de expansão específicos: $=var para divisão de palavras, $~var para globbing (ou ${~var} ; $~=var para ambos).

Os outros shells que não têm esse tipo de problema são fish e rc e seus descendentes ( es , akanga ).

Em (t)csh :

cmd "$var"

ajuda, mas não é suficiente, pois não funciona se $var contiver caracteres de nova linha. Lá você precisa:

cmd $var:q
    
por 14.08.2014 / 10:41