Por que lê -r eat text? [duplicado]

0

Eu tenho um arquivo names.txt com a linha superior do texto sendo

51 Pipe-line\Closed3
while read one two three; do

  new=$(echo $two|tr '\' '/')
  echo $one
  echo $two
  echo $three
  echo $new

done < ./names.txt
001011_-_Portfolio\UW\Old\NID50_Future_022814.xlsx

Eu gostaria de escrever novos nomes de arquivos substituindo \ por /

Eu escrevi um script.sh e invoquei usando sh script.sh . Minha primeira tentativa ...

51
Pipe-lineClosed300001011_-_PortfolioUWOldNID50_Future_022814.xlsx

Pipe-lineClosed300001011_-_PortfolioUWOldNID50_Future_022814.xlsx
 while read -r one two three; do

  new=$(echo $two|tr '\' '/')
  echo $one
  echo $two
  echo $three
  echo $new

done < ./names.txt

Isso comeu o / char. Descobri que passar um -r mostrará o / , então minha próxima tentativa foi

51
Pipe-line\Closed3

Pipe-line/Closed3
51 Pipe-line\Closed3
while read one two three; do

  new=$(echo $two|tr '\' '/')
  echo $one
  echo $two
  echo $three
  echo $new

done < ./names.txt
001011_-_Portfolio\UW\Old\NID50_Future_022814.xlsx

Isso consome metade do nome do arquivo. O que está acontecendo? Como faço para que isso funcione?

    
por lonewarrior556 29.03.2017 / 16:42

3 respostas

4

Não é o read , mas o echo .

I wrote a script.sh and invoked it using sh script.sh.

No Debian e no Ubuntu, sh é dash , em que echo avalia escapes de barra invertida no estilo C em seus argumentos:

$ dash -c 'foo="foo
$ dash -c 'foo="foo%pre%0bar"; echo "$foo"; printf "%s\n" "$foo"' 
foo
foo%pre%0bar
0bar"; echo "$foo"; printf "%s\n" "$foo"' foo foo%pre%0bar

O echo0 é transformado no byte NUL, que aparentemente termina a cadeia que echo produz. Citando a variável não ajuda aqui, já que ela apenas altera o processamento da linha de comando do shell antes do próprio comando ser executado, e aqui está o echo em si que lida com as barras invertidas.

Este é um problema de portabilidade conhecido, descrito em mais detalhes aqui: Por que printf melhor que echo?

Por exemplo, -e do Bash faz o processamento de contrabarra se receber o argumento bash script.sh .

A pergunta foi marcada originalmente com , portanto, se você quiser execute o script usando o Bash, execute-o com sh script.sh , não %code% .

    
por 29.03.2017 / 17:20
1

Isso pode ser feito de uma maneira muito mais simples e robusta com o sed:

sed -i 's|\|/|g' myfile

Dá:

cat myfile     51 Pipe-line / Closed3 / 00001011 _-_ Portfólio / UW / Antigo / NID50_Futuro_022814.xls

EDITAR :

Após o seu comentário, esta é a maneira que eu conseguiria isso:

for i in $(cat test | awk '{print $2}')
do
  mv $i 'sed 's|\|/|g' <<< $i'
done
    
por 29.03.2017 / 16:51
0

Apenas isso será suficiente:

tr '\' / < names.txt
    
por 29.03.2017 / 18:00