Bash - Manipolazione continua delle stringhe


11
#!/bin/bash

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

Esiste comunque un modo per incollare queste due linee in un solo strato?

Risposte:


12

FILE=$(basename "${1/%.jpeg/.jpg}") ha funzionato per me.

test:

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

contenuto della sceneggiatura:

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

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

echo "$FILE"

Dato che le due linee sono in qualche modo intercambiabili, questa soluzione è finora la più pulita ... Se le linee non sono intercambiabili sedsarà sicuramente necessario, immagino.
gsklee,

11

Non puoi nidificare espansioni in bash (né in ksh, ash e altre shell a parte zsh). Questa è solo una limitazione estetica, poiché, come illustrato, è possibile assegnare un'espressione intermedia a una variabile temporanea. È un po 'fastidioso per i one-liner, ma negli script è probabilmente migliore per la leggibilità.

È possibile evitare di utilizzare l'utilità esterna basenamee utilizzare invece un costrutto di manipolazione di stringhe:

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

Qui, succede che puoi riscrivere il tuo script per mettere il comando di sostituzione all'esterno . Questo non è un fenomeno generale, né ottieni altro che una certa sensazione di una linea.

Zsh, nel bene e nel male, ti consente di nidificare espansioni:

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

Oppure potresti usare il costrutto incorporato di zsh invece di basename:

FILE=${${1:t}/%.jpeg/.jpg}

4

Vorrei andare per:

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

Il secondo parametro per basename è un suffisso da rimuovere dal nome del file (vedi man basename)


3

È possibile utilizzare un singolo sedcomando come nel seguente:

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

2

Incorporando sed, questo dovrebbe fare il trucco:

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

(Questo non risponde esattamente alla tua domanda perché non posso; non sono sicuro che sia possibile.)


1

I ${}costrutti Bash funzionano con nomi di variabili , quindi non c'è modo di incorporare direttamente un comando. L'approccio di @ sr_ è un'alternativa se non ti dispiace il fork extra.


1

La linea

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

può essere ridotto e reso più portatile con

FILE=$(basename "${1%.jpeg}.jpg")
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.