Eliminar múltiples sufijos posibles

Eliminar múltiples sufijos posibles

Ejemplo: quiero crear un comando rápido para reducir imágenes (para mi navegador de archivos).

...
FN="/tmp/some-image.jpg"
gm convert "$FN" -resize 50% "$(dirname $FN)/$(basename $FN .jpg/png/gif).jpg"
...

¿Cómo puedo especificar que se debe eliminar más de un sufijo?

Respuesta1

basenamesolo se necesita un sufijo para eliminar y proporciona el nombre base (elimina los componentes del directorio) que no desea que esté allí de todos modos, por lo que basenameno es realmente la herramienta adecuada para sus necesidades.

La herramienta tradicional para extraer datos de una cadena es expr:

FN_without_extension=$(expr "x$FN" : 'x\(.*\)\.')

Pero los shells modernos (como zsh, bash, ksh, ash, yashtodos compatibles con POSIX sh...) tienen operadores integrados para eso, por lo que casi nunca los necesitas exprhoy en día (y es mejor evitarlos ya que tiene algunos problemas).

${var%pattern}

elimina el patrón coincidente de la parte (más pequeña) del final del$var

gm convert "$FN" -resize 50% "${FN%.*}.jpg"

A los shells les gusta tcsho zshtienen operadores para eliminar extensiones. Zsh:

gm convert $FN -resize 50% $FN:r.jpg

( rparanombre raíz).

Si desea eliminar la extensión, solo si es una de jpg/png/gif, entonces eso se vuelve más complicado y depende del shell.

Con zsh:

gm convert $FN -resize 50% ${FN%.(jpg|png|gif)}.jpg

Con ksh:

gm convert "$FN" -resize 50% "${FN%.@(jpg|png|gif)}.jpg"

Con bash:

shopt -s extglob
gm convert "$FN" -resize 50% "${FN%.@(jpg|png|gif)}.jpg"

Con expr:

gm convert "$FN" -resize 50% "$(
  expr \( "x$FN" : '\(.*\)\.png$' \| \
          "x$FN" : '\(.*\)\.jpg$' \| \
          "x$FN" : '\(.*\)\.gif$' \| "x$FN" \) : 'x\(.*\)')".jpg

(sí, eso es complicado y es para solucionar algunos de los problemas de expr).

Con algunas exprimplementaciones, se puede simplificar a:

expr \( "x$FN" : '\(.*\)\.\(png\|jpg\|gif\)$' \| "x$FN" \) : 'x\(.*\)'

También podrías usar sed:

FN_without_ext=$(printf '%s\n' "$FN" |
  sed -e '$!b' -e 's/\.png$//;t' -e 's/\.gif$//;t' -e 's/\.jpg$//')

Si desea que no distinga entre mayúsculas y minúsculas, puede reemplazar png/gif/jpgen todas las soluciones anteriores con [pP][nN][gG]..., algunos shells/herramientas también pueden hacer coincidencias que no distingan entre mayúsculas y minúsculas:

zsh:

 setopt extendedglob
 FN_without_ext=${FN%.(#i)(gif|png|jpg)}

ksh93:

 FN_without_ext=${FN%.~(i:gif|png|jpg)}

bash:

 shopt -s nocasematch
 LC_ALL=C
 if [[ $FN =~ (.*)\.(gif|png|jpg)$ ]]; then
   FN_without_ext=${BASH_REMATCH[1]}
 else
   FN_without_ext=$FN
 fi

GNU sed:

 FN_without_ext=$(printf '%s\n' "$FN" | sed -r '$s/\.(png|gif|jpg)$//I')

Respuesta2

¿Esto debería funcionar? Básicamente se trata de eliminar .mp3o .wavextensiones:

$ basename -s .wav $(basename -s .mp3 'some_file.mp3')
some_file
$ basename -s .wav $(basename -s .mp3 'some_file.wav')
some_file
$ basename -s .wav $(basename -s .mp3 'some_file.rs') 
some_file.rs

información relacionada