agregar texto al nombre del archivo antes de la extensión

25

Me gustaría agregar texto al final del nombre de archivo pero antes de la extensión. En este momento estoy intentando

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

la salida es

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

Quiero que sea

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
fuente

Respuestas:

27

Usando la expansión de parámetros POSIX estándar :

for f in *.shp; do printf '%s\n' "${f%.shp}_poly.shp"; done
jw013
fuente
Impresionante, eso es exactamente lo que necesitaba.
Sam007
1
Podría ser mejor con una explicación de cómo funciona. La respuesta de Doug es bastante fácil, por otro lado.
Sarge Borsch
@SargeBorsch ¿Qué necesitas explicar? Mi respuesta, el fragmento de la pregunta y la respuesta de Doug solo difieren en unos pocos caracteres, y la respuesta de Doug explica incluso menos que la mía, así que no sé qué es lo que quieres. Si solo compara la diferencia en las dos salidas en la pregunta, debería ser trivialmente fácil descubrir qué hacen. Puedo explicar por qué mi respuesta es preferible a la de Doug. 1. Lo uso printfcon una cadena de formato en lugar de la menos portátil echo. 2. Utilizo la expansión de parámetros que es más eficiente que llamar a un binario externo ( basename) para una tarea tan simple.
jw013
Entonces el comando para cambiar el nombre de los archivos sería este:for f in *.shp; do mv $f ${f%.shp}_poly.shp; done
Patch92
6

A veces hay una herramienta llamada "renombrar" instalada.

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

Puede que no sea portátil pero es fácil de usar.

Chad Clark
fuente
1
Este es el único que funcionó para mí, ¡gran respuesta!
wanderer0810
4

Utilizar esta:

for file in *.shp; do echo $(basename $file .shp)_poly.shp; done
doneal24
fuente
3
El uso basenamees más lento y menos eficiente que dejar que el shell haga el trabajo por sí mismo. Esto puede ser notable para un gran número de archivos.
jw013
Además, faltan comillas y --sy falla para los nombres de archivo que tienen caracteres de nueva línea antes de .shp.
Stéphane Chazelas
Gracias por dar una respuesta con la que realmente puedo trabajar para mi propósito. Esta es una gran ayuda, no un código de golf. (leyendo sobre esto ... me doy cuenta de que puede haber sonado como si estuviera siendo sarcástico. Más apremiante sobre las otras respuestas aquí que la suya. Gracias de nuevo)
Tim
3

Esto funcionó mejor para mí:

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

Vinnie James
fuente
Bueno, esto se parece mucho a la respuesta aceptada, excepto que probablemente quieras for f in *.webm, olvidaste citar la ${f}y te falta una --.
Stéphane Chazelas
1
La respuesta aceptada no funciona en OSX, solo imprime los nuevos nombres de archivo, en realidad no cambia el nombre de los archivos
Vinnie James
1
Por supuesto, le muestra cómo usar expansiones de shell para obtener el nuevo nombre de archivo, en respuesta a la pregunta que también genera un nombre de archivo (con echo), pero no el requerido.
Stéphane Chazelas
1

Si están en diferentes ubicaciones, ejecute: -

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

Como la pregunta es, bashno hay necesidad de utilidades externas, ya que puede usar bash regexps :

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