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
basename
solo 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 basename
no 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
, yash
todos compatibles con POSIX sh
...) tienen operadores integrados para eso, por lo que casi nunca los necesitas expr
hoy 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 tcsh
o zsh
tienen operadores para eliminar extensiones. Zsh:
gm convert $FN -resize 50% $FN:r.jpg
( r
paranombre 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 expr
implementaciones, 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/jpg
en 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 .mp3
o .wav
extensiones:
$ 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