adicionando texto ao nome do arquivo antes da extensão

25

Gostaria de adicionar texto ao final do nome do arquivo, mas antes da extensão. Agora eu estou tentando,

for f in *.shp; do echo $f_poly; done

a saída é,

Quercus_acutifolia.shp_poly
Quercus_agrifolia.shp_poly
Quercus_corrugata.shp_poly
Quercus_cortesii.shp_poly
Quercus_costaricensis.shp_poly
Quercus_havardii.shp_poly
Quercus_hemisphaerica.shp_poly
Quercus_kelloggii.shp_poly
Quercus_knoblochii.shp_poly
Quercus_laceyi.shp_poly

Eu quero que seja

Quercus_acutifolia_poly.shp
Quercus_agrifolia_poly.shp
Quercus_corrugata_poly.shp
Quercus_cortesii_poly.shp
Quercus_costaricensis_poly.shp
Quercus_havardii_poly.shp
Quercus_hemisphaerica_poly.shp
Quercus_kelloggii_poly.shp
Quercus_knoblochii_poly.shp
Quercus_laceyi_poly.shp
Sam007
fonte

Respostas:

27

Usando a expansão de parâmetro POSIX padrão :

for f in *.shp; do printf '%s\n' "${f%.shp}_poly.shp"; done
jw013
fonte
Impressionante é exatamente o que eu precisava.
Sam007
11
Pode ser melhor com uma explicação de como funciona. A resposta de Doug é bem fácil, por outro lado.
precisa
@SargeBorsch O que você precisa explicar? Minha resposta, o trecho da pergunta e a resposta de Doug diferem apenas em alguns caracteres, e a resposta de Doug explica ainda menos que a minha, então não sei o que você quer. Se você apenas comparar a diferença nas duas saídas da pergunta, deve ser fácil descobrir o que elas fazem. Eu posso explicar por que minha resposta é preferível à de Doug. 1. Uso printfcom uma string de formato em vez de menos portátil echo. 2. Uso expansão de parâmetros que é mais eficiente do que chamar um binário externo ( basename) para uma tarefa tão simples.
jw013
Em seguida, o comando para renomear os arquivos seria o seguinte:for f in *.shp; do mv $f ${f%.shp}_poly.shp; done
Patch92
6

Às vezes, existe uma ferramenta chamada "renomear" instalada.

rename 's/\.shp$/_poly.shp/' *shp

Pode não ser portátil, mas é fácil de usar.

Chad Clark
fonte
11
Este é o único que funcionou para mim, ótima resposta!
wanderer0810
4

Usa isto:

for file in *.shp; do echo $(basename $file .shp)_poly.shp; done
doneal24
fonte
3
O uso basenameé mais lento e menos eficiente do que deixar o shell fazer o trabalho sozinho. Isso pode ser perceptível para um número muito grande de arquivos.
jw013
Além disso, há aspas --es ausentes e isso falha nos nomes de arquivos que possuem caracteres de nova linha antes de .shp.
Stéphane Chazelas
Obrigado por dar uma resposta com a qual posso trabalhar para o meu propósito. Isso é ajuda do bash, não código de golfe. (lendo sobre isso. Sei que parece que eu estava sendo sarcástico. Mais emocionante sobre as outras respostas aqui do que as suas. Obrigado novamente)
Tim
3

Isso funcionou melhor para mim:

for f in *; do NEW=${f%.webm}_2016.webm; mv ${f} "${NEW}"; done

Vinnie James
fonte
Bem, isso se parece muito com a resposta aceita, exceto que você provavelmente quer for f in *.webm, você esqueceu de citar ${f}e está faltando um --.
Stéphane Chazelas
11
O trabalho resposta does not aceite no OSX, ele só imprime os novos nomes de arquivos, ele doesnt realmente renomear os arquivos
Vinnie James
11
Obviamente, ele mostra como usar expansões de shell para obter o novo nome de arquivo, em resposta à pergunta que também está exibindo um nome de arquivo (com echo), mas não o necessário.
Stéphane Chazelas
1

Se eles estiverem em locais diferentes, execute: -

for i in ` find /root/test/ -name "*.shp" ` ;
do
  mv $i ` echo $i | sed 's/.shp$/_poly.shp/g' ` ;
done
Shankey Ravi
fonte
1

Como a pergunta é para, bashnão há necessidade de utilitários externos, pois você pode usar o bash regexps :

for i in *.shp
do
    mv -v "${i}" "${i%.*}_MYSUFFIX.${i##*.}"
done
ccpizza
fonte