Beim Schreiben eines Skripts wollte ich alle Zeichen außer Alpha ([a-zA-Z]) durch einen Zeilenumbruch ersetzen. Per Definition sollte tr bei Verwendung des Flags -c (Set Complement) alle Zeichen, die nicht in SET1 enthalten sind, durch das in SET2 angegebene Zeichen ersetzen. Trotzdem funktioniert es nicht wie erwartet... Versuchen Sie Folgendes:
echo '[[:lower:]]' | tr -c '[a-zA-Z]' '\n'
Ausgabe, die ich bekomme:
[[
lower
]]
Wie man sieht, ersetzt es Spalten, aber nicht eckige Klammern, die es ersetzen soll.
Kann das jemand klarstellen?
Antwort1
tr
interpretiert Zeichenklassen nicht in diesem Regex-Stil.
[a-zA-Z]
wird als eine Menge von interpretiert [
, der Zeichenbereich von a
bis z
und ]
.
Daher ist sein Komplement die Menge an Zeichen, die alle Zeichen außer umfasst [
, den Zeichenbereich von a
bis z
und ]
.
Aus diesem Grund werden [
sie ]
nicht ersetzt.
Um ein beliebiges nicht-alphabetisches Zeichen zu ersetzen, geben Sie einfach a-zA-Z
als Ergänzung des zu ersetzenden Satzes Folgendes an:
echo '[[:lower:]]' | tr -c 'a-zA-Z' '\n'
% echo '[[:lower:]]' | tr -c 'a-zA-Z' '\n'
lower
%