Wenn Sie die Bash verwenden, müssen Sie nicht einmal den Befehl grep
:
files="*.jpg"
regex="[0-9]+_([a-z]+)_[0-9a-z]*"
for f in $files # unquoted in order to allow the glob to expand
do
if [[ $f =~ $regex ]]
then
name="${BASH_REMATCH[1]}"
echo "${name}.jpg" # concatenate strings
name="${name}.jpg" # same thing stored in a variable
else
echo "$f doesn't match" >&2 # this could get noisy if there are a lot of non-matching files
fi
done
Es ist besser, die Regex in eine Variable zu setzen. Einige Muster funktionieren nicht, wenn sie wörtlich enthalten sind.
Dabei werden =~
was der Regex-Match-Operator der Bash ist. Die Ergebnisse der Übereinstimmung werden in einem Array namens $BASH_REMATCH
. Die erste Fanggruppe wird in Index 1 gespeichert, die zweite (falls vorhanden) in Index 2 usw. Index Null ist die vollständige Übereinstimmung.
Sie sollten sich darüber im Klaren sein, dass diese Regex (und die Regex, die grep
) passt zu jedem der folgenden und weiteren Beispiele, die vielleicht nicht das sind, wonach Sie suchen:
123_abc_d4e5
xyz123_abc_d4e5
123_abc_d4e5.xyz
xyz123_abc_d4e5.xyz
Um das zweite und vierte Beispiel zu eliminieren, machen Sie Ihre Regex wie folgt:
^[0-9]+_([a-z]+)_[0-9a-z]*
die besagt, dass die Zeichenkette Start mit einer oder mehreren Ziffern. Das Karat steht am Anfang der Zeichenfolge. Wenn Sie am Ende der Regex ein Dollar-Zeichen hinzufügen, etwa so:
^[0-9]+_([a-z]+)_[0-9a-z]*$
dann wird auch das dritte Beispiel eliminiert, da der Punkt nicht zu den Zeichen in der Regex gehört und das Dollarzeichen das Ende der Zeichenkette darstellt. Beachten Sie, dass auch das vierte Beispiel diese Übereinstimmung nicht aufweist.
Wenn Sie GNU grep
(etwa 2,5 oder später, glaube ich, wenn die \K
Operator wurde hinzugefügt):
name=$(echo "$f" | grep -Po '(?i)[0-9]+_\K[a-z]+(?=_[0-9a-z]*)').jpg
El \K
Operator (Look-Behind-Operator mit variabler Länge) bewirkt, dass das vorangehende Muster übereinstimmt, aber die Übereinstimmung nicht in das Ergebnis aufgenommen wird. Die Entsprechung mit fester Länge ist (?<=)
- würde das Muster vor der schließenden Klammer eingefügt werden. Sie müssen \K
wenn Quantifizierer mit unterschiedlich langen Zeichenfolgen übereinstimmen können (z. B. +
, *
, {2,4}
).
El (?=)
Operator findet Muster mit fester oder variabler Länge und wird "Vorausschau" genannt. Außerdem wird die übereinstimmende Zeichenfolge nicht in das Ergebnis aufgenommen.
Um die Übereinstimmung unabhängig von der Groß- und Kleinschreibung zu machen, wird die (?i)
Operator verwendet wird. Er wirkt sich auf die Muster aus, die ihm folgen, daher ist seine Position von Bedeutung.
Die Regex muss möglicherweise angepasst werden, je nachdem, ob der Dateiname weitere Zeichen enthält. Sie werden feststellen, dass ich in diesem Fall ein Beispiel für die Verkettung einer Zeichenfolge zur gleichen Zeit zeige, in der die Teilzeichenfolge erfasst wird.