Shell Scripting: ¿cómo utilizar parte de la ruta del archivo como nombre de archivo?

Shell Scripting: ¿cómo utilizar parte de la ruta del archivo como nombre de archivo?

Tengo un grupo de directorios, cada uno de los cuales contiene exactamente 1 imagen jpeg, así:

/psds/folder1/image.jpg
/psds/someotherfolder/picture.jpg
/psds/yetanotherfolder/thumbnail.jpg

¿Cuál es la forma adecuada de cambiar el nombre de los archivos JPEG al nombre de la carpeta que los contiene? Lo que quiero es:

/psds/folder1/folder1.jpg
/psds/someotherfolder/someotherfolder.jpg
/psds/yetanotherfolder/yetanotherfolder.jpg

Respuesta1

Ejecute los siguientes comandos dentro /psdsdel directorio.

for f in ./*; do
    if [ -d "$f" ] ; then
        cd "$f"
        mv *.jpg "$f.jpg"
        cd ..
    fi
done

Si tiene 3 carpetas dentro /psdsdel directorio como se muestra a continuación,

/psds/folder1/image1.jpg
/psds/folder2/image2.jpg
/psds/folder3/image3.jpg

Después de ejecutar el comando anterior, los archivos pasarán a llamarse como,

/psds/folder1/folder1.jpg
/psds/folder2/folder2.jpg
/psds/folder3/folder3.jpg

Respuesta2

Puedes usar elexpansión de parámetros de shellconstruye ${VAR#PREFIX}y ${VAR%SUFFIX}para obtener el valor de una variable con el prefijo o sufijo especificado eliminado. Si PREFIX es un patrón, se elimina la cadena coincidente más corta; con ##o %%, se elimina la coincidencia más larga. Estas construcciones están disponibles en todos los shells de tipo sh (Bourne/POSIX), no solo en bash.

Si el valor de VARes una ruta como /path/to/directory/file, entonces "${VAR%/*}"es el directorio que contiene el archivo y "${VAR##*/}"es el nombre del archivo sin la parte del directorio. Tenga en cuenta que "${VAR%/*}"solo es correcto si $VARcontiene al menos uno /y "${VAR##*/}"solo si VARno termina en /. También hay utilidades llamadas dirnamey basenameque son más fiables a este respecto. Lo mismo ${VAR##*.}ocurre con la última ampliación.

for x in /psds/*/*.jpg; do
  dir="${x%/*}"
  mv "$x" "$dir/${dir##*/}.jpg"
done

Como de costumbre, zsh tiene una forma ligeramente críptica pero breve y sencilla. ElzmvLa función es conveniente para cambiar el nombre de archivos en masa.

autoload -U zmv   # put this in your .zshrc
zmv '/psds/(*)/*.jpg' '/psds/$1/$1.jpg'

Otro enfoque utilizandomodificadores de expansión de la historiasobre la expansión de parámetros:

zmv '/psds/*/*.jpg' '$f:h/$f:h:t.$f:e'

información relacionada