Bash - Manipulación continua de cuerdas

11
#!/bin/bash

FILE="$(basename "$1")"
FILE="${FILE/%.jpeg/.jpg}"

¿Hay alguna forma de pegar estas dos líneas en una sola línea?

gsklee
fuente

Respuestas:

12

FILE=$(basename "${1/%.jpeg/.jpg}") trabajó para mi.

prueba:

bash-$ ./test.sh /tmp/foo.jpeg
foo.jpg

contenido del guión:

bash-$ cat test.sh 
#!/usr/bin/bash

FILE=$(basename "${1/%.jpeg/.jpg}")

echo "$FILE"
Tim Kennedy
fuente
Dado que las dos líneas son un poco intercambiables, esta solución es hasta ahora la más perfecta ... Si las líneas no son intercambiables sed, definitivamente será necesario, supongo.
gsklee
11

No puede anidar expansiones en bash (ni en ksh, ash y otras conchas aparte de zsh). Esto es solo una limitación cosmética, ya que, como ilustra, puede asignar una expresión intermedia a una variable temporal. Es un poco molesto para las frases sencillas, pero en los scripts es posiblemente mejor para la legibilidad.

Podría evitar usar la utilidad externa basenamey usar una construcción de manipulación de cadenas en su lugar:

FILE="${1##*/}"; FILE="${FILE/%.jpeg/.jpg}"

Aquí, sucede que puede reescribir su script para colocar la sustitución del comando en el exterior . Ese no es un fenómeno general, ni obtienes nada más que un cierto sentimiento de una línea.

Zsh, para bien o para mal, te permite anidar expansiones:

FILE=${$(basename $1)/%.jpeg/.jpg}    # using basename
FILE=${${1##*/}/%.jpeg/.jpg}          # using string rewriting

O podría usar la construcción incorporada de zsh en lugar de basename:

FILE=${${1:t}/%.jpeg/.jpg}
Gilles 'SO- deja de ser malvado'
fuente
4

Yo iría por:

FILE=$(basename $1 .jpeg).jpg

El segundo parámetro para basename es un sufijo que se eliminará del nombre del archivo (ver man basename)

Chirlo
fuente
3

Puede usar un solo sedcomando como en el siguiente:

FILE=$(sed 's/.*\///;s/\.jpeg$/.jpg/' <<<"$1")
enzotib
fuente
2

Incorporando sed, esto debería hacer el truco:

FILE="$(basename "$1" | sed s/\.jpeg$/.jpg/)"

(Esto no responde exactamente a su pregunta porque no puedo; no estoy seguro de si es posible).

sr_
fuente
1

Las ${}construcciones Bash funcionan con nombres de variables , por lo que no hay forma de incrustar un comando directamente. El enfoque de @ sr_ es una alternativa si no le importa la bifurcación adicional.

l0b0
fuente
1

La línea

FILE=$(basename "${1/%.jpeg/.jpg}")

se puede acortar y hacer más portátil con

FILE=$(basename "${1%.jpeg}.jpg")
Peter John Acklam
fuente