Bash - ciągłe manipulowanie strunami


11
#!/bin/bash

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

Czy w ogóle można skleić te dwie linie razem w jednej linijce?

Odpowiedzi:


12

FILE=$(basename "${1/%.jpeg/.jpg}") pracował dla mnie.

test:

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

zawartość skryptu:

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

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

echo "$FILE"

Ponieważ dwie linie są w pewnym sensie wymienne, to rozwiązanie jest jak dotąd najładniejsze ... Jeśli linie nie są wymienne sed, na pewno będzie to potrzebne.
gsklee

11

Nie możesz zagnieżdżać rozszerzeń w bash (ani w ksh, ash i innych powłokach oprócz zsh). Jest to jedynie ograniczenie kosmetyczne, ponieważ jak zilustrujesz, możesz przypisać wyrażenie pośrednie do zmiennej tymczasowej. Jest to trochę denerwujące dla jedno-liniowych, ale w skryptach jest prawdopodobnie lepsze dla czytelności.

Można uniknąć używania zewnętrznego narzędzia basenamei zamiast tego użyć konstrukcji do manipulacji ciągiem:

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

Tutaj zdarza się, że możesz przepisać skrypt, aby umieścić podstawienie polecenia na zewnątrz . To nie jest ogólne zjawisko, ani nie zyskujesz nic innego niż pewne poczucie jednowarstwowości.

Zsh, na dobre lub na złe, pozwala zagnieżdżać rozszerzenia:

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

Lub możesz użyć wbudowanej konstrukcji zsh zamiast basename:

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

4

Wybrałbym:

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

Drugi parametr do nazwy basename to sufiks, który należy usunąć z nazwy pliku (patrz man basename)


3

Możesz użyć jednego sedpolecenia, jak poniżej:

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

2

Włączenie sedpowinno załatwić sprawę:

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

(To nie do końca odpowiada na twoje pytanie, ponieważ nie mogę; nie jestem pewien, czy to możliwe).


1

Konstrukcje Bash ${}działają z nazwami zmiennych , więc nie ma możliwości bezpośredniego osadzenia polecenia. Podejście @ sr_ jest alternatywą, jeśli nie przeszkadza ci dodatkowy widelec.


1

Linia

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

można go skrócić i uczynić bardziej przenośnym

FILE=$(basename "${1%.jpeg}.jpg")
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.