Saya memiliki satu server tertentu yang menunjukkan perilaku aneh saat menggunakan tr. Berikut adalah contoh dari server yang berfungsi:
-bash-3.2$ echo "abcdefghijklmnopqrstuvwxyz1234567890"|tr -d [a-z]
1234567890
-bash-3.2$
Itu masuk akal bagi saya.
Namun, ini dari server 'khusus':
[root@host~]# echo "abcdefghijklmnopqrstuvwxyz1234567890"|tr -d [a-z]
abcdefghijklmnpqrstuvwxyz1234567890
Seperti yang Anda lihat, menghapus semua karakter huruf kecil gagal. TAPI, itu telah menghapus huruf 'o'
Bagian yang menarik adalah dua contoh berikut, yang sama sekali tidak masuk akal bagi saya:
[root@host~]# echo "abcdefghijklmnopqrstuvwxyz1234567890"|tr -d [a-n]
opqrstuvwxyz1234567890
[root@host~]# echo "abcdefghijklmnopqrstuvwxyz1234567890"|tr -d [a-o]
abcdefghijklmnpqrstuvwxyz1234567890
[root@host~]#
(lagi, 'o' dihapus pada contoh terakhir)
Adakah yang tahu apa yang sedang terjadi di sini? Saya tidak dapat mereproduksi pada kotak linux lain yang saya gunakan.
shell
command-line
wildcards
tr
Chris
sumber
sumber
tr
rentang ditulis tanpa melampirkan[...]
. Jaditr -d '[a-z]'
akan membunuha-z
, dan juga karakter[
dan]
. Gunakantr -d a-z
untuk membunuh hanya surata-z
.Jawaban:
Anda memiliki file bernama
o
di direktori saat inishell akan memperluas
[a-z]
string jika kecocokan ditemukan.Ini disebut ekspansi pathname, menurut
man bash
bash akan melakukan ekspansi.
sumber
echo
:touch o ; echo tr -d [a-z]
memberikan ini:tr -d o
Apa yang terjadi
Shell (bash) melihat argumennya
[a-z]
. Itu adalah pola wildcard ( gabus ), yang cocok dengan huruf kecil apa pun¹. Karenanya shell mencari nama file yang cocok dengan pola ini. Ada tiga kasus:tr
melihat argumen-d
dan[a-z]
. Inilah yang terjadi pada sebagian besar mesin Anda.tr
melihat argumen-d
dan nama file. Ini terjadi di server, dan file yang cocok dipanggilo
karena kita dapat melihat bahwatr
menghapus surat ituo
.tr
melihat tiga argumen atau lebih:-d
dan nama file. Karenatr
mengharapkan satu argumen setelahnya-d
, itu akan mengeluh.Apa yang seharusnya Anda lakukan
Jika ada karakter khusus dalam argumen perintah, Anda harus menghindarinya. Letakkan argumen dalam tanda kutip tunggal
'…'
(ini adalah cara paling sederhana, ada yang lain). Di dalam kutipan tunggal, semua karakter berdiri sendiri kecuali kutipan tunggal itu sendiri. Jika ada satu kutipan di dalam argumen, gantilah dengan'\''
.Namun perhatikan bahwa ini mungkin masih bukan yang Anda maksudkan! Ini memberitahu Anda
tr
untuk menghapus huruf kecil dan tanda kurung. Ini setara dengantr -d ']a-z['
,tr '[]a-z'
, dll Untuk menghapus huruf kecil, gunakanArgumen untuk
tr
adalah serangkaian karakter. Anda menempatkan tanda kurung di sekitar set karakter dalam ekspresi reguler atau pola wildcard untuk menunjukkan bahwa itu adalah set karakter. Tetapitr
bekerja pada satu karakter pada satu waktu. Argumen baris perintahnya adalah apa yang Anda masukkan ke dalam tanda kurung .Anda memang membutuhkan tanda kurung untuk menunjukkan kelas karakter . Dalam ekspresi reguler, Anda menggunakan tanda kurung di dalam tanda kurung untuk menunjukkan kelas karakter, misalnya
[[:lower:]]*
cocok dengan sejumlah huruf kecil,[[:lower:]_]*
cocok dengan sejumlah huruf kecil dan garis bawah. Dalam argumentr
, Anda memerlukan set tanpa tanda kurung di sekitarnya, jaditr -d '[:lower:]'
hapus huruf kecil,tr -d '[:lower:]_'
hapus huruf kecil dan garis bawah, dll.¹ Di beberapa tempat mungkin cocok dengan karakter lain .
sumber
tr -d '[a-z]'
dengan/usr/bin/tr
. Dengan/usr/xpg4/bin/tr
,tr -d a-z
berfungsi tetapitr -d '[a-z]'
tidak menghapus[
atau]
./usr/xpg4/bin/tr -d '[a-z]'
tidak menghapus[
atau]
tampaknya diperbaiki di Solaris 11.