Ich ersetze aus einem Feed-Titel alle Zeichen außer Buchstaben und Ziffern durch einen Bindestrich, um das Ergebnis als sicheren Dateinamen für jedes Dateisystem zu verwenden:
$ t="Episodie 06: No hope of riding home (NEW) - Advanced grammar"
$ echo ${t//[^A-Za-z0-9]/-}
Episodie-06--No-hope-of-riding-home--NEW----Advanced-grammar
Ich möchte jedoch alle sich wiederholenden Striche mit einem einzigen wie verdichten Episodie-06-No-hope-of-riding-home-NEW-Advanced-grammar
Ich habe festgestellt, dass ich es mit einer Zwei-Pass-Substitution erreichen kann:
$ t="Episodie 06: No hope of riding home (NEW) - Advanced grammar"
$ tmp=${t//[^A-Za-z0-9]/-}
$ echo ${tmp//--/-}
Episodie-06-No-hope-of-riding-home-NEW--Advanced-grammar
Ich dachte, ich könnte es in einem einzigen Durchgang tun wie:
$ echo ${t//[^A-Za-z0-9]+/-}
aber es funktioniert nicht.
Irgendeine Ahnung?
Hinweis: Ich möchte nicht mit sed
oder anderen Tools gehen
shopt
und welche Muscheln es unterstützen.shopt
ist spezifisch für Bash. Die aktivierte Mustersyntax ist immer in allen ksh-Varianten verfügbar. In zsh muss diese Syntax mit aktiviert werdensetopt ksh_glob
. POSIX hat keine solche Funktion, seine Platzhalter sind weniger leistungsfähig als reguläre Ausdrücke. Andere Shells als bash / ksh / zsh, was in der Praxis heutzutage meistens Asche bedeutet, bleiben in der Regel bei POSIX-Platzhaltern.echo "$t" | sed -r 's/[^[:alnum:]]+/-/g; s/^-|-$//'
. Ich akzeptiere Ihre Antwort, da sie genau das tut, was in Frage gestellt wurde.${var/PATTERN/REPLACEMENT}
Konstrukt auch spezifisch für ksh / bash / zsh ist.sed
da ich die Syntax und das Verhalten besser kenne. Ich kann leicht eine Anweisung hinzufügen, um Start- / Nachstriche zu entfernen. Ich muss mich nicht um\n
char kümmern . Istsed
viel weniger verfügbar alstr
?tr
ist ein gutes Werkzeug für diesen Jobquelle
tr
... Allerdings habe ich versucht, es in Bash zu erledigen, sonst würde ich gehen mitsed
:echo "$t" | sed -r 's/[^A-Za-z0-9]+/-/g'
Note: I don't want to go with sed or other tools
Wenn Sie bei Pure Bash bleiben möchten, müssen Sie sich mit der Zwei-Pass-Lösung zufrieden geben. Bash-String-Ersetzungen verwenden Globs wie bei der Pfadnamenerweiterung und keine regulären Ausdrücke. Die einzigen Sonderzeichen in Kleckse sind
*
,?
und[]
, deren grobe Äquivalente in reguläre Ausdrücke sind.*
,.
und[]
. Werfen Sie einen Blick auf die Wooledge Wiki und diebash(1)
Manpage Abschnitte aufParameter Expansion
undPathname Expansion
für weitere Informationen.Nur als Kommentar ist eine Erweiterung in zwei Durchgängen in Pure Bash wahrscheinlich immer noch schneller als der Versuch, dasselbe durch Aufrufen eines externen Programms zu tun, sodass ich mir darüber keine allzu großen Sorgen machen würde.
quelle
shopt -s extglob; t="${t//+([^A-Za-z0-9])/-}"