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?

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"

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}

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)


3

Puede usar un solo sedcomando como en el siguiente:

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

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).


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.


1

La línea

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

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

FILE=$(basename "${1%.jpeg}.jpg")
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.