Mam jeden konkretny serwer, który wykazuje dziwne zachowanie podczas używania tr. Oto przykład z działającego serwera:
-bash-3.2$ echo "abcdefghijklmnopqrstuvwxyz1234567890"|tr -d [a-z]
1234567890
-bash-3.2$
To ma dla mnie idealny sens.
Wynika to jednak z serwera „specjalnego”:
[root@host~]# echo "abcdefghijklmnopqrstuvwxyz1234567890"|tr -d [a-z]
abcdefghijklmnpqrstuvwxyz1234567890
Jak widać, usuwanie wszystkich małych liter kończy się niepowodzeniem. ALE usunęła literę „o”
Interesującą częścią są dwa następujące przykłady, które nie mają dla mnie żadnego sensu:
[root@host~]# echo "abcdefghijklmnopqrstuvwxyz1234567890"|tr -d [a-n]
opqrstuvwxyz1234567890
[root@host~]# echo "abcdefghijklmnopqrstuvwxyz1234567890"|tr -d [a-o]
abcdefghijklmnpqrstuvwxyz1234567890
[root@host~]#
(ponownie „o” zostało usunięte w ostatnim przykładzie)
Czy ktoś ma pojęcie, co się tutaj dzieje? Nie mogę reprodukować na żadnym innym urządzeniu z linuksem, którego używam.
shell
command-line
wildcards
tr
Chris
źródło
źródło
tr
zakresy są zapisywane bez otaczania[...]
. Więctr -d '[a-z]'
zabijea-z
, a także postacie[
i]
. Służytr -d a-z
do zabijania tylko litera-z
.Odpowiedzi:
masz plik o nazwie
o
w bieżącym katalogupowłoka rozwinie
[a-z]
ciąg, jeśli zostanie znalezione dopasowanie.Nazywa się to rozszerzaniem nazw ścieżek
man bash
bash wykona ekspansję.
źródło
echo
:touch o ; echo tr -d [a-z]
daje to:tr -d o
Co się dzieje
Powłoka (bash) widzi argument
[a-z]
. Jest to wzór wieloznaczny ( glob ), który pasuje do każdej małej litery¹. Dlatego powłoka szuka nazwy pliku pasującej do tego wzorca. Istnieją trzy przypadki:tr
widzi argumenty-d
i[a-z]
. Tak dzieje się na większości twoich maszyn.tr
widzi argumenty-d
oraz nazwę pliku. Dzieje się tak na serwerze i wywoływany jest odpowiedni plik,o
ponieważ widzimy, żetr
usunął listo
.tr
widzi trzy lub więcej argumentów:-d
i nazwy plików. Ponieważtr
oczekuje później jednego argumentu-d
, będzie narzekać.Co powinieneś był zrobić
Jeśli w argumencie polecenia są znaki specjalne, musisz je uciec. Umieść argument w pojedynczych cudzysłowach
'…'
(jest to najprostszy sposób, istnieją inne). Wewnątrz pojedynczych cudzysłowów wszystkie postacie są sobą, z wyjątkiem samego pojedynczego cudzysłowu. Jeśli wewnątrz argumentu znajduje się pojedynczy cytat, zamień go na'\''
.Pamiętaj jednak, że prawdopodobnie nie to miałeś na myśli! Mówi
tr
to o usuwaniu małych liter i nawiasów kwadratowych. To odpowiedniktr -d ']a-z['
,tr '[]a-z'
itp Aby usunąć małe litery, stosowanieArgumentem
tr
jest zestaw znaków. Umieszczasz nawiasy wokół zestawu znaków w wyrażeniu regularnym lub wzorze wieloznacznym, aby wskazać, że jest to zestaw znaków. Aletr
działa na jedną postać na raz. Argumenty wiersza poleceń są tym, co należy umieścić w nawiasach .Potrzebujesz nawiasów, aby wskazać klasy znaków . W wyrażeniu regularnym używasz nawiasów wewnątrz nawiasów, aby wskazać klasę znaków, np.
[[:lower:]]*
Pasuje do dowolnej liczby małych liter,[[:lower:]_]*
pasuje do dowolnej liczby małych liter i podkreśleń. Jako argumenttr
potrzebujesz zestawu bez otaczających go nawiasów, więctr -d '[:lower:]'
usuwa małe litery,tr -d '[:lower:]_'
usuwa małe litery i podkreślenia itp.¹ W niektórych lokalizacjach może pasować do innych znaków .
źródło
tr -d '[a-z]'
z/usr/bin/tr
. Dzięki/usr/xpg4/bin/tr
,tr -d a-z
działa, aletr -d '[a-z]'
nie usuwa[
ani]
./usr/xpg4/bin/tr -d '[a-z]'
nie[
]