Ich habe einen bestimmten Server, der bei der Verwendung von tr ein seltsames Verhalten zeigt. Hier ist ein Beispiel von einem funktionierenden Server:
-bash-3.2$ echo "abcdefghijklmnopqrstuvwxyz1234567890"|tr -d [a-z]
1234567890
-bash-3.2$
Das macht für mich vollkommen Sinn.
Dies ist jedoch vom "speziellen" Server:
[root@host~]# echo "abcdefghijklmnopqrstuvwxyz1234567890"|tr -d [a-z]
abcdefghijklmnpqrstuvwxyz1234567890
Wie Sie sehen können, schlägt das Löschen aller Kleinbuchstaben fehl. ABER es hat den Buchstaben 'o' gelöscht
Der interessante Teil sind die folgenden zwei Beispiele, die für mich überhaupt keinen Sinn ergeben:
[root@host~]# echo "abcdefghijklmnopqrstuvwxyz1234567890"|tr -d [a-n]
opqrstuvwxyz1234567890
[root@host~]# echo "abcdefghijklmnopqrstuvwxyz1234567890"|tr -d [a-o]
abcdefghijklmnpqrstuvwxyz1234567890
[root@host~]#
(Auch hier wird das 'o' im letzten Beispiel gelöscht.)
Hat jemand eine Idee was hier los ist? Ich kann auf keiner anderen Linux-Box, die ich verwende, reproduzieren.
shell
command-line
wildcards
tr
Chris
quelle
quelle
tr
Bereiche werden ohne Beilage geschrieben[...]
. Sotr -d '[a-z]'
wird getöteta-z
, und auch Charaktere[
und]
. Verwenden Sietr -d a-z
diese Option , um nur Buchstaben zu tötena-z
.Antworten:
Sie haben eine Datei mit dem Namen
o
im aktuellen VerzeichnisDie Shell erweitert den
[a-z]
String, wenn eine Übereinstimmung gefunden wird.Dies wird laut
man bash
Bash führt eine Erweiterung durch.
quelle
echo
:touch o ; echo tr -d [a-z]
gibt diese:tr -d o
Was ist los
Die Shell (Bash) sieht das Argument
[a-z]
. Dies ist ein Platzhaltermuster (ein Glob ), das mit jedem Kleinbuchstaben übereinstimmt¹. Daher sucht die Shell nach einem Dateinamen, der diesem Muster entspricht. Es gibt drei Fälle:tr
sieht die Argumente-d
und[a-z]
. Dies geschieht auf den meisten Ihrer Maschinen.tr
sieht die Argumente-d
und den Dateinamen. Dies geschieht auf dem Server, und die übereinstimmende Datei wird aufgerufen,o
da wir sehen können, dasstr
der Buchstabe gelöscht wurdeo
.tr
sieht drei oder mehr Argumente:-d
und die Dateinamen. Datr
nachher ein einziges Argument erwartet wird-d
, wird es sich beschweren.Was du hätte tun sollen
Wenn das Argument eines Befehls Sonderzeichen enthält, müssen Sie diese maskieren. Setzen Sie das Argument in einfache Anführungszeichen
'…'
(dies ist der einfachste Weg, es gibt andere). In einfachen Anführungszeichen stehen alle Zeichen für sich selbst, mit Ausnahme des einfachen Anführungszeichens. Wenn das Argument ein einfaches Anführungszeichen enthält, ersetzen Sie es durch'\''
.Beachten Sie jedoch, dass dies wahrscheinlich immer noch nicht das ist, was Sie gemeint haben! Dies weist
tr
an, Kleinbuchstaben und eckige Klammern zu löschen. Es ist äquivalent zutr -d ']a-z['
,tr '[]a-z'
usw. Kleinbuchstaben zu löschen, verwendenDas Argument für
tr
ist ein Zeichensatz. Sie setzen Klammern um einen Zeichensatz in einem regulären Ausdruck oder einem Platzhaltermuster, um anzuzeigen, dass es sich um einen Zeichensatz handelt. Arbeitet aber jeweilstr
an einem einzelnen Charakter. Die Befehlszeilenargumente werden in Klammern gesetzt .Sie benötigen Klammern, um Zeichenklassen anzugeben . In einem regulären Ausdruck verwenden Sie Klammern in Klammern, um eine Zeichenklasse anzugeben, z. B. eine
[[:lower:]]*
beliebige Anzahl von Kleinbuchstaben, eine[[:lower:]_]*
beliebige Anzahl von Kleinbuchstaben und Unterstrichen. Im Argument vontr
benötigen Sie die Menge ohne die umgebenden Klammern, also werdentr -d '[:lower:]'
Kleinbuchstaben,tr -d '[:lower:]_'
Kleinbuchstaben und Unterstriche usw. gelöscht.¹ In einigen Gebietsschemas kann es mit anderen Zeichen übereinstimmen .
quelle
tr -d '[a-z]'
mit benötigen/usr/bin/tr
. Mit/usr/xpg4/bin/tr
,tr -d a-z
funktioniert abertr -d '[a-z]'
nicht gelöscht[
noch]
./usr/xpg4/bin/tr -d '[a-z]'
weder gelöscht[
noch]
anscheinend in Solaris 11 behoben.