script bash funciona com apenas no debug

4

Estou tentando remover caracteres de um nome de arquivo.

arquivos

#ls
Peter, Paul & Mary - The Very Best of Peter, Paul and Mary (AutoFlac).flac
Peter, Paul & Mary - The Very Best of Peter, Paul and Mary (AutoFlac).log
Peter, Paul & Mary - The Very Best of Peter, Paul and Mary.cue

O que eu quero para a saída:

#ls
Peter, Paul & Mary - The Very Best of Peter, Paul and Mary.cue
Peter, Paul & Mary - The Very Best of Peter, Paul and Mary.flac
Peter, Paul & Mary - The Very Best of Peter, Paul and Mary.log

script

#!/bin/bash
SUFFIX="(AutoFLAC)"
#search directory for file with a suffix of (AutoFLAC)
for entry in *$SUFFIX*
do
   #remove a leading space and (AutoFLAC) from the file name
   FILENAME='echo $entry | sed 's/ (AutoFLAC)//''
   echo "$entry"
   echo "$FILENAME"
   #change the old file name for the new file name
   mv  "$entry" "$FILENAME"
 done

Se eu adicionar -x , funciona.

Mac-Attack:edit-file-names $ ./edit-file-names1.sh 
+ SUFFIX='(AutoFLAC)'
+ for entry in '*$SUFFIX*'
++ echo Peter, Paul '&' Mary - The Very Best of Peter, Paul and Mary '(AutoFLAC).flac'
++ sed 's/ (AutoFLAC)//'
+ FILENAME='Peter, Paul & Mary - The Very Best of Peter, Paul and Mary.flac'
+ echo 'Peter, Paul & Mary - The Very Best of Peter, Paul and Mary (AutoFLAC).flac'
Peter, Paul & Mary - The Very Best of Peter, Paul and Mary (AutoFLAC).flac
+ echo 'Peter, Paul & Mary - The Very Best of Peter, Paul and Mary.flac'
Peter, Paul & Mary - The Very Best of Peter, Paul and Mary.flac
+ mv 'Peter, Paul & Mary - The Very Best of Peter, Paul and Mary (AutoFLAC).flac' 
'Peter, Paul & Mary - The Very Best of Peter, Paul and Mary.flac'
+ for entry in '*$SUFFIX*'
++ echo Peter, Paul '&' Mary - The Very Best of Peter, Paul and Mary '(AutoFLAC).log'
++ sed 's/ (AutoFLAC)//'
+ FILENAME='Peter, Paul & Mary - The Very Best of Peter, Paul and Mary.log'
+ echo 'Peter, Paul & Mary - The Very Best of Peter, Paul and Mary (AutoFLAC).log'
Peter, Paul & Mary - The Very Best of Peter, Paul and Mary (AutoFLAC).log
+ echo 'Peter, Paul & Mary - The Very Best of Peter, Paul and Mary.log'
Peter, Paul & Mary - The Very Best of Peter, Paul and Mary.log
+ mv 'Peter, Paul & Mary - The Very Best of Peter, Paul and Mary (AutoFLAC).log' 'Peter, Paul & Mary - The Very Best of Peter, Paul and Mary.log'
Mac-Attack:edit-file-names $ ls
Peter, Paul & Mary - The Very Best of Peter, Paul and Mary.cue
Peter, Paul & Mary - The Very Best of Peter, Paul and Mary.flac
Peter, Paul & Mary - The Very Best of Peter, Paul and Mary.log

Sem o -x :

Mac-Attack:edit-file-names $ ./edit-file-names2.sh 
*(AutoFLAC)*
*(AutoFLAC)*
mv: rename *(AutoFLAC)* to *(AutoFLAC)*: No such file or directory

Percepções, pensamentos?

    
por librarian 05.02.2012 / 22:12

2 respostas

4

Há, evidentemente, algo estranho acontecendo em torno da correspondência de caracteres curingas sem distinção entre maiúsculas e minúsculas. De acordo com a saída ls , os nomes dos arquivos contêm (AutoFlac) , enquanto o seu script procura (AutoFLAC) . As ferramentas Unix tradicionalmente consideram que dois nomes de arquivos são os mesmos apenas se forem idênticos byte a byte; não há nada embutido para correspondência insensível a maiúsculas e minúsculas. O Bash parece se comportar de maneira inconsistente em um sistema de arquivos insensível a maiúsculas e minúsculas, isso pode ser um bug.

Seu script seria mais robusto se você usasse aspas duplas em torno das substituições de variáveis. Se você não fizer isso, o bash (como outros shells) executa o globbing no resultado da substituição da variável. Esta pode ser a fonte do seu problema. Sempre coloque aspas duplas em torno de substituições de variáveis e substituições de comandos: "$foo" , "$(foo)" a menos que você saiba que deseja executar a divisão de palavras e globbing no resultado. Além disso, seu script com aspas duplas ausentes não funcionaria em alguns nomes de arquivos, por exemplo, com sequências de espaço em branco que não são um único espaço.

Eu também recomendo fazer a substituição de texto dentro do shell, há menos risco de manchar nomes de arquivos dessa maneira.

SUFFIX="(AutoFlac)"
for entry in *"$SUFFIX"*; do
  target=${entry/ $SUFFIX/}
  mv -- "$entry" "$target"
done

Não há como forçar a correspondência de caracteres curingas que não diferenciam maiúsculas de minúsculas, mas você pode fazer com que seu script ignore maiúsculas e minúsculas, fazendo sua correspondência.

SUFFIX="(autoflac)"
for entry in *; do
  if [[ ${entry,,} = *$SUFFIX* ]]; then
    # Remove everything from the last space to the last .
    mv -- "$entry" "${entry% *}.${entry##*.}"
  fi
done
    
por 06.02.2012 / 02:01
0

Se o shell não encontrar nenhum arquivo correspondente para um padrão glob, ele executará o loop uma vez com o padrão glob intacto. * (AutoFLAC) * é sua entrada devido a esse comportamento.

    
por 15.07.2014 / 02:57

Tags