Bash - Kontinuierliche String-Manipulation


11
#!/bin/bash

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

Gibt es überhaupt eine Möglichkeit, diese beiden Linien zu einem Einzeiler zusammenzukleben?

Antworten:


12

FILE=$(basename "${1/%.jpeg/.jpg}") arbeitete für mich.

Prüfung:

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

Skriptinhalt:

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

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

echo "$FILE"

Da die beiden Leitungen irgendwie austauschbar sind, ist diese Lösung bisher die sauberste ... Wenn die Leitungen nicht austauschbar sind, sedwird sie definitiv benötigt, denke ich.
Gsklee

11

Sie können Erweiterungen nicht in Bash (oder in Ksh, Asche und anderen Muscheln außer Zsh) verschachteln. Dies ist nur eine kosmetische Einschränkung, da Sie, wie Sie veranschaulichen, einer temporären Variablen einen Zwischenausdruck zuweisen können. Es ist ein wenig nervig für Einzeiler, aber in Skripten ist es wohl besser für die Lesbarkeit.

Sie können die Verwendung des externen Dienstprogramms vermeiden basenameund stattdessen ein Konstrukt zur Manipulation von Zeichenfolgen verwenden:

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

Hier kann es vorkommen, dass Sie Ihr Skript neu schreiben können, um die Befehlsersetzung nach außen zu verschieben . Das ist kein allgemeines Phänomen, und Sie gewinnen auch nichts anderes als ein bestimmtes Einzeiler-Gefühl.

Zsh, zum Guten oder zum Schlechten, lässt Sie Erweiterungen verschachteln:

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

Oder Sie können das integrierte Konstrukt von zsh anstelle von basename:

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

4

Ich würde gehen für:

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

Der zweite Parameter für den Basisnamen ist ein Suffix, das aus dem Dateinamen entfernt werden soll (siehe man basename).


3

Sie können einen einzelnen sedBefehl wie folgt verwenden:

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

2

Die Einbeziehung sedsollte dieser den Trick:

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

(Dies beantwortet Ihre Frage nicht genau, weil ich es nicht kann. Ich bin mir nicht sicher, ob es möglich ist.)


1

Die Bash- ${}Konstrukte arbeiten mit Variablennamen , sodass ein Befehl nicht direkt eingebettet werden kann. Der Ansatz von @ sr_ ist eine Alternative, wenn Ihnen die zusätzliche Gabel nichts ausmacht.


1

Die Linie

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

kann gekürzt und tragbarer gemacht werden mit

FILE=$(basename "${1%.jpeg}.jpg")
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.