lote renomeia nomes de arquivos incluindo espaços e padrões [duplicados]

2

Gostaria de renomear um monte de arquivos que são nomeados em uma forma geral de

text1 text2 [firstname.lastname] text3 ... textn.ext

Eu quero remover o texto [firstname.lastname] do nome de um arquivo. Para simplificar a tarefa, assuma que [firstname.lastname] é um nome e sobrenome fixo para todos os arquivos.

Eu uso o Ubuntu 12.04, e eu tentei o seguinte comando,

$ find . -name "*.ext" -print | xargs sed -i 's/[firstname.lastname]//g'

mas não funciona.

    
por Rasoul 03.07.2013 / 22:31

2 respostas

1

sed modifica o conteúdo de um arquivo. Use rename em seu lugar.

$ find . -name "*.ext" -print0 | xargs -0 rename 's/\[firstname\.lastname\]//g'

Passe o sinal rename the -n para fazer uma execução a seco. Dessa forma, você pode testar seu comando sem realmente renomear nenhum arquivo.

Também fiz algumas outras alterações no código.

  • Adicionar -print0 a find e -0 a xargs permite que o comando manipule espaços. Por padrão, find usa novas linhas para separar os nomes de arquivos gerados e xargs espera receber nomes de arquivos separados por espaço em branco. -print0 e -0 fazem esses dois comandos tratarem os bytes nulos como delimitadores de nome de arquivo. Veja esta questão para mais informações .

  • rename usa expressões regulares Perl , que tratam . , [ e ] especialmente. Eles devem ser escapados neste caso.

por 03.07.2013 / 22:46
4

Usando o Bash globbing:

for i in *.ext; do
    echo mv -nv -- "$i" "${i/firstname.lastname/}"
done

Remova o eco se estiver satisfeito com isso.

Se você precisar entrar em subdiretórios:

shopt -s globstar
for i in **/*.ext; do
    echo mv -nv -- "$i" "${i/firstname.lastname/}"
done

Remova o echo quando estiver satisfeito com isso.

Usando find :

find . -name '*.ext' -exec bash -c 'echo mv -nv -- "$0" "${0/firstname.lastname/}"' {} \;

Remova o echo quando estiver satisfeito com isso.

Que tal um método que renomeie, removendo qualquer padrão do formulário xxx.yyy (portanto, ele removerá o firstname.lastname do nome do arquivo, sendo john.doe ou james.brown ): para isso (usando o primeiro método ):

shopt -s extglob
for i in *.ext; do
    echo mv -nv -- "$i" "${i/+([[:graph:]])\.+([[:graph]])/}"
done

ou usando o segundo método:

shopt -s globstar extglob
for i in **/*.ext; do
    echo mv -nv -- "$i" "${i/+([[:graph:]])\.+([[:graph:]])/}"
done

ou usando o método find :

find . -name '*.ext' -exec bash -c 'shopt -s extglob; echo mv -nv -- "$0" "${0/+([[:graph:]])\.+([[:graph:]])/}"' {} \;

Se o padrão firstname.lastname estiver sempre entre espaços, você também pode usar a substituição de padrões:

"${i/*([[:space:]])+([[:graph:]])\.+([[:graph:]])*([[:space:]])/ }"

para deixar apenas um espaço.

Observação. Todos esses métodos são 100% seguros em relação a nomes de arquivos com espaços e outros símbolos engraçados.

Espero que isso ajude!

    
por 03.07.2013 / 23:27

Tags