2017-07-25 13 views
3

voraus zu extrahieren habe ich folgendes Format für Dateinamen: filename_1234.svgBash: Wie Zahlen von _ und gefolgt von

Wie kann ich die Zahlen abrufen durch einen Unterstrich vorangestellt und gefolgt von einem Punkt. Es kann vor dem .svg

zwischen 3.59 Zahlen habe ich versucht:

width=${fileName//[^0-9]/} 

aber wenn die Datei als auch eine Zahl enthält, werden alle Zahlen im Dateinamen zurückgeben, z

file6name_1234.svg 

Ich fand Lösungen für zwei Unterstrichen (und es in ein Array aufteilen), aber ich bin auf der Suche nach einem Weg für den Unterstrich sowie den Punkt zu überprüfen.

Antwort

1

können Sie einfach verwenden Parameter Expansion mit Teilzeichenfolge Entfernung einfach aus dem zu trimmen rechts bis zu und einschließlich der '.', dann trimmen vom links bis zu und einschließlich der '_' , die gewünschte Nummer belassen, z

$ width=filename_1234.svg; val="${width%.*}"; val="${val##*_}"; echo $val 
1234 

Anmerkung:# Ordnungen von links-erstem Auftreten während ## trimmen letzten Auftritt. % und %% funktionieren auf die gleiche Weise von der rechts.

Erklärt:

  • width=filename_1234.svg - width hält Ihre Dateinamen

  • val="${width%.*}" - val hält filename_1234

  • val="${val##*_}" - schließlich val hält 1234

Natürlich ist es nicht notwendig, einen temporären Wert wie val zu verwenden, wenn Ihre Absicht ist, dass width die Breite halten soll. Ich habe gerade eine Temperatur verwendet, um den ursprünglichen Inhalt von width zu schützen. Wenn Sie die resultierende Nummer in width möchten, ersetzen Sie einfach val durch width überall oben und arbeiten Sie direkt auf width.

Anmerkung 2: Verwendung Shell-Fähigkeiten wie Parameter Expansions verhindert einen separaten Subshell zu schaffen und einen separaten Prozess Laichen das auftritt, wenn ein Dienstprogramm wie sed Verwendung grep oder awk (oder etwas, das nicht Teil der Schale ist für diese Angelegenheit).

2

Versuchen Sie, den folgenden Code:

filename="filename_6_1234.svg" 
if [[ "$filename" =~ ^(.*)_([^.]*)\..*$ ]]; 
then 
    echo "${BASH_REMATCH[0]}" #will display 'filename_6_1234.svg' 
    echo "${BASH_REMATCH[1]}" #will display 'filename_6' 
    echo "${BASH_REMATCH[2]}" #will display '1234' 
fi 

Erläuterung:

  • =~: bash Operator für regex Vergleich
  • ^(.*)_([^.])\..*$: Wir suchen nach einem beliebigen Zeichen, gefolgt von einem Unterstrich, von jedem gefolgt Zeichen, die durch einen Punkt und eine Erweiterung folgt. Wir schaffen 2 -Abscheidung Gruppen, eine für vor dem letzten Strich, ein für nach
  • BASH_REMATCH: Array mit den erfassten Gruppen
+0

Wenn ich diesen Code ausführen, bekomme ich: e_1 und e. Auch wenn der Dateiname einen anderen Unterstrich enthält, sagen wir: file6_name_1234.svg gibt es aus: 6_n und 6 (obwohl es nicht zum Muster passt: Unterstrich-Ziffern-Punkt -> extrahiere die Ziffern) Jede Hilfe wird geschätzt. – TheRed

+1

@TheRed hat die Regex geändert, um Ihren Punkt zu adressieren – Aserre

0

I

sed 's!_! !g' | awk '{print "_" $NF}' 

verwenden würde von filename_1234.svg zu _1234 erhalten .svg dann

sed 's!svg!!g' 

, um die Erweiterung loszuwerden.

0

verwenden Wenn Sie IFS gesetzt, Sie Bash Build-in read nutzen können.

Dieser teilt die Dateinamen durch Unterstreichungen und Punkte und speichert das Ergebnis in dem Array a.

IFS='_.' read -a a <<<'file1b2aname_1234.svg' 

Und das nimmt das vorletzte Element aus dem Array.

echo ${a[-2]} 
0

Es gibt eine Lösung mit cut:

name="file6name_1234.svg" 
num=$(echo "$name" | cut -d '_' -f 2 | cut -d '.' -f 1) 
echo "$num" 

-d zur Angabe eines Trennzeichen ist.

-f bezieht sich auf das gewünschte Feld.

Ich weiß nichts über die Leistung, aber es ist einfach zu verstehen und einfach zu warten.

Verwandte Themen