1184 Stimmen

Teilstring in Bash extrahieren

Angesichts eines Dateinamens in der Form someletters_12345_moreleters.ext Ich möchte die 5 Ziffern extrahieren und sie in eine Variable einfügen.

Um das zu verdeutlichen, habe ich einen Dateinamen mit einer Anzahl von x Zeichen, dann eine fünfstellige Sequenz, die von einem einzelnen Unterstrich auf beiden Seiten umgeben ist, und dann eine weitere Reihe von x Zeichen. Ich möchte die fünfstellige Zahl nehmen und sie in eine Variable einfügen.

Ich bin sehr daran interessiert, wie viele verschiedene Möglichkeiten es gibt, dies zu erreichen.

13voto

Darron Punkte 20861

Sie können ohne Unterprozesse arbeiten:

shopt -s extglob
front=${input%%_+([a-zA-Z]).*}
digits=${front##+([a-zA-Z])_}

Eine sehr kleine Variante davon wird auch in ksh93 funktionieren.

13voto

Meine Antwort wird mehr Kontrolle über das haben, was Sie von Ihrem String erwarten. Hier ist der Code, wie Sie extrahieren können 12345 aus Ihrem String

str="someletters_12345_moreleters.ext"
str=${str#*_}
str=${str%_more*}
echo $str

Dies ist effizienter, wenn Sie etwas extrahieren wollen, das beliebige Zeichen enthält wie abc oder irgendwelche Sonderzeichen wie _ o - . Zum Beispiel: Wenn Ihre Zeichenkette wie folgt aussieht und Sie alles, was nach someletters_ und vor _moreleters.ext :

str="someletters_123-45-24a&13b-1_moreleters.ext"

Mit meinem Code können Sie genau angeben, was Sie wollen. Erläuterung:

#* Er entfernt die vorangehende Zeichenkette einschließlich des passenden Schlüssels. Hier ist der erwähnte Schlüssel _ % Es wird die folgende Zeichenfolge einschließlich des passenden Schlüssels entfernt. Hier ist der erwähnte Schlüssel '_more*'.

Machen Sie selbst ein paar Experimente und Sie werden feststellen, dass dies interessant ist.

11voto

codist Punkte 99

Hier ist eine Präfix-Suffix-Lösung (ähnlich den Lösungen von JB und Darron), die dem ersten Ziffernblock entspricht und nicht von den umgebenden Unterstrichen abhängt:

str='someletters_12345_morele34ters.ext'
s1="${str#"${str%%[[:digit:]]*}"}"   # strip off non-digit prefix from str
s2="${s1%%[^[:digit:]]*}"            # strip off non-digit suffix from s1
echo "$s2"                           # 12345

11voto

Campa Punkte 3872

Ich liebe sed die Fähigkeit, mit Regex-Gruppen umzugehen:

> var="someletters_12345_moreletters.ext"
> digits=$( echo "$var" | sed "s/.*_\([0-9]\+\).*/\1/p" -n )
> echo $digits
12345

Eine etwas allgemeinere Option wäre no anzunehmen, dass Sie einen Unterstrich haben _ die den Beginn der Ziffernfolge markiert, wodurch beispielsweise alle Nicht-Ziffern vor der Ziffernfolge entfernt werden können: s/[^0-9]\+\([0-9]\+\).*/\1/p .


> man sed | grep s/regexp/replacement -A 2
s/regexp/replacement/
    Attempt to match regexp against the pattern space.  If successful, replace that portion matched with replacement.  The replacement may contain the special  character  &  to
    refer to that portion of the pattern space which matched, and the special escapes \1 through \9 to refer to the corresponding matching sub-expressions in the regexp.

Mehr dazu, falls Sie sich mit regexps nicht so gut auskennen:

  • s steht für _s_substitute
  • [0-9]+ entspricht 1+ Ziffern
  • \1 verweist auf die Gruppe n.1 der Regex-Ausgabe (Gruppe 0 ist die gesamte Übereinstimmung, Gruppe 1 ist in diesem Fall die Übereinstimmung innerhalb der Klammern)
  • p Flagge ist für _p_drucken

Alle Fluchten \ sind dazu da, die sed Die Regexp-Verarbeitung funktioniert.

9voto

Rick Osman Punkte 69

Gegeben test.txt ist eine Datei, die "ABCDEFGHIJKLMNOPQRSTUVWXYZ" enthält.

cut -b19-20 test.txt > test1.txt # This will extract chars 19 & 20 "ST" 
while read -r; do;
> x=$REPLY
> done < test1.txt
echo $x
ST

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X