J'ai un serveur particulier qui présente un comportement étrange lors de l'utilisation de tr. Voici un exemple d'un serveur qui fonctionne:
-bash-3.2$ echo "abcdefghijklmnopqrstuvwxyz1234567890"|tr -d [a-z]
1234567890
-bash-3.2$
Cela me semble parfaitement logique.
Cependant, cela provient du serveur «spécial»:
[root@host~]# echo "abcdefghijklmnopqrstuvwxyz1234567890"|tr -d [a-z]
abcdefghijklmnpqrstuvwxyz1234567890
Comme vous pouvez le voir, la suppression de tous les caractères minuscules échoue. MAIS, il a supprimé la lettre «o»
La partie intéressante est les deux exemples suivants, qui n'ont aucun sens pour moi:
[root@host~]# echo "abcdefghijklmnopqrstuvwxyz1234567890"|tr -d [a-n]
opqrstuvwxyz1234567890
[root@host~]# echo "abcdefghijklmnopqrstuvwxyz1234567890"|tr -d [a-o]
abcdefghijklmnpqrstuvwxyz1234567890
[root@host~]#
(encore une fois, le «o» est supprimé dans le dernier exemple)
Quelqu'un a-t-il une idée de ce qui se passe ici? Je ne peux pas reproduire sur une autre boîte Linux que j'utilise.
shell
command-line
wildcards
tr
Chris
la source
la source
tr
plages sont écrites sans les entourer[...]
. Ainsitr -d '[a-z]'
tueraa-z
, et aussi des personnages[
et]
. Utiliseztr -d a-z
pour tuer seulement des lettresa-z
.Réponses:
vous avez un fichier nommé
o
dans le répertoire courantshell étendra la
[a-z]
chaîne si une correspondance est trouvée.C'est ce qu'on appelle l'extension du nom de chemin, selon
man bash
bash effectuera l'expansion.
la source
echo
:touch o ; echo tr -d [a-z]
donne ceci:tr -d o
Qu'est-ce qui se passe
Le shell (bash) voit l'argument
[a-z]
. C'est un motif générique (un glob ), qui correspond à n'importe quelle lettre minuscule¹. Par conséquent, le shell recherche un nom de fichier correspondant à ce modèle. Il y a trois cas:tr
voit les arguments-d
et[a-z]
. C'est ce qui se passe sur la plupart de vos machines.tr
voit les arguments-d
et le nom de fichier. Cela se produit sur le serveur, et le fichier correspondant est appeléo
car nous pouvons voir quetr
la lettre a été suppriméeo
.tr
voit au moins trois arguments:-d
et les noms de fichiers. Commetr
attend un seul argument après-d
, il va se plaindre.Ce que tu aurais dû faire
S'il y a des caractères spéciaux dans l'argument d'une commande, vous devez les échapper. Mettez l'argument entre guillemets simples
'…'
(c'est le moyen le plus simple, il y en a d'autres). À l'intérieur des guillemets simples, tous les personnages se distinguent, à l'exception de la guillemet simple lui-même. S'il y a une seule citation à l'intérieur de l'argument, remplacez-la par'\''
.Notez cependant que ce n'est probablement pas ce que vous vouliez dire! Cela indique
tr
de supprimer les lettres minuscules et les crochets. Il est équivalent àtr -d ']a-z['
,tr '[]a-z'
etc. Pour supprimer des lettres minuscules, utilisezL'argument de
tr
est un jeu de caractères. Vous mettez des crochets autour d'un jeu de caractères dans une expression régulière ou un motif générique pour indiquer qu'il s'agit d'un jeu de caractères. Maistr
fonctionne sur un seul personnage à la fois. Ses arguments de ligne de commande sont ce que vous mettriez entre crochets .Vous avez besoin de crochets pour indiquer les classes de caractères . Dans une expression régulière, vous utilisez des crochets entre crochets pour indiquer une classe de caractères, par exemple,
[[:lower:]]*
correspond à n'importe quel nombre de lettres minuscules,[[:lower:]_]*
correspond à n'importe quel nombre de lettres minuscules et de soulignements. Dans l'argument detr
, vous avez besoin de l'ensemble sans ses crochets, donctr -d '[:lower:]'
supprime les lettres minuscules,tr -d '[:lower:]_'
supprime les lettres minuscules et les traits de soulignement, etc.¹ Dans certains pays, il peut correspondre à d'autres caractères .
la source
tr -d '[a-z]'
de/usr/bin/tr
. Avec/usr/xpg4/bin/tr
,tr -d a-z
fonctionne maistr -d '[a-z]'
ne supprime[
ni]
./usr/xpg4/bin/tr -d '[a-z]'
pas de suppression[
ni de]
correction apparente dans Solaris 11.