Konversi semua teks dari huruf besar ke huruf kecil dan sebaliknya?
17
Pertanyaan saya adalah bagaimana saya bisa mengubah semua teks dari huruf besar menjadi huruf kecil dan sebaliknya? Itu untuk mengubah kasus semua huruf. Itu harus dilakukan dengan sedpenggantian entah bagaimana.
Yang kedua mengasumsikan GNU seddan kasing alternatif di input. Gunakan sed -re 's/([[:lower:]]?)([[:upper:]]?)/\U\1\L\2/g'sebagai gantinya (masih spesifik GNU). Yang pertama hanya mengonversi 26 huruf latin ASCII, sedangkan yang kedua mengonversi setiap huruf yang dikenali oleh lokal Anda. Yang trhanya masuk akal di lokal ASCII. Yang perlsatu hanya berfungsi untuk huruf latin ASCII.
Stéphane Chazelas
16
POSIXly, itu tidak bisa dilakukan sedkecuali dengan menyediakan set lengkap surat yang ingin Anda transliterasikan seperti yang ditunjukkan oleh @cuonglm .
Itu bisa dilakukan dengan tr, dan itu truntuk (transliterate):
tr '[:lower:][:upper:]' '[:upper:][:lower:]'
Namun, di Linux, ada batasannya. Dari 3tr implementasi yang biasa ditemukan pada sistem berbasis Linux:
dengan GNU tr, yang hanya berfungsi untuk set karakter byte tunggal. Misalnya, di Stéphane Chazelasdalam lokal UTF-8, yang memberi sTéPHANE cHAZELASbukansTÉPHANE cHAZELAS . Itu adalah keterbatasan GNU tr.
dengan tr dari toolchest heirloom, itu tidak berhasil (Anda dapatkan stéphane chazelas).
Itu bukan jenis busybox tr .
Pada FreeBSD itu berfungsi dengan baik. Anda akan mengharapkannya berfungsi dengan baik di sistem Unix bersertifikat juga.
Jadi di dunia desktop hanya OSX yang melakukannya? Mengapa itu tidak berhasil? Apakah hanya implementasi yang berbeda karena tampaknya ada offset konstan dalam nilai hex antara versi huruf kecil dari aksen char dan rekan huruf besar itu?
1
@ illuminÉ, tidak yakin apa yang Anda maksud dengan dunia desktop . AFAICS, masalahnya adalah dengan GNU, sebagian besar Unices memiliki "desktop". Terlepas dari ASCII dan beberapa rangkaian iso8859, saya tidak menyadari bahwa Anda dapat menggeneralisasi hal hex offset, dan itu tidak masuk akal dengan pengkodean seperti UTF-8. Misalnya dalam UTF-8, huruf besar ⴠ(e2 b4 a0) adalah Ⴠ(e1 83 80); baik i(69) dan ı(c4 b1) memiliki I(49) sebagai huruf besar (kecuali di lokal Turki di mana imenjadi İ). Alasan tidak bekerja dengan GNU tradalah karena GNU trbekerja dengan byte dan bukan karakter.
Stéphane Chazelas
Saya semacam berarti arus utama tetapi tidak masuk akal benar-benar terima kasih untuk kepala. Saya hanya melihat karakter aksen Prancis (dan benar-benar hanya "é") dan membuat asumsi yang sangat sederhana, lupa lagi bahwa ini tentang byte. Tapi yang pusaka? Saya akan membaca jawaban itu lagi!
1
@ illuminÉ, untuk pusaka, ini masalah yang berbeda, sepertinya hanya mendukung satu kejadian [:lower:]atau [:upper:](jadi yang pertama diabaikan). Bahkan di Perancis, œ -> Œadalah c5 93 -> c5 92dalam UTF-8 dan bd -> bcdi iso8859-15.
Stéphane Chazelas
2
Meskipun ini memiliki keterbatasan yang sama yang telah disebutkan sebagai trsolusi yang ditawarkan oleh Stéphane Chazelas, ini adalah cara lain untuk melakukannya:
Saya membuang stderrke /dev/nullsana karena ddjuga menyediakan statistik dari semua operasinya pada 2deskriptor file. Ini bisa bermanfaat tergantung pada apa yang Anda lakukan, tetapi tidak untuk demonstrasi ini. Semua hal lain yang dapat Anda lakukan ddmasih berlaku, misalnya:
Itu tidak menukar kasus (karena aBctidak dikonversi ke AbC).
Stéphane Chazelas
1
@ StéphaneChazelas - benar, tapi kecuali saya salah paham, bukan itu pertanyaannya, kan?
mikeserv
2
Jika tujuan utama Anda adalah untuk mengkonversi file dari kelas bawah ke kelas atas, mengapa tidak Anda gunakan trdan STDOUTuntuk mengkonversi file Anda:
$cat FILENAME | tr a-z A-Z > FILENAME2
Di mana FILENAMEfile asli Anda. Di mana FILENAME2file hasil konversi Anda.
tr
akan lebih cocok daripadased
.Jawaban:
Inilah cara langsung
sed
:atau cara yang lebih pendek dengan GNU
sed
, bekerja dengan karakter apa pun yang ada <-> konversi huruf kecil di lokal Anda:jika Anda dapat menggunakan alat lain, seperti:
perl
(terbatas pada surat ASCII):perl
(lebih umum):sumber
sed
dan kasing alternatif di input. Gunakansed -re 's/([[:lower:]]?)([[:upper:]]?)/\U\1\L\2/g'
sebagai gantinya (masih spesifik GNU). Yang pertama hanya mengonversi 26 huruf latin ASCII, sedangkan yang kedua mengonversi setiap huruf yang dikenali oleh lokal Anda. Yangtr
hanya masuk akal di lokal ASCII. Yangperl
satu hanya berfungsi untuk huruf latin ASCII.POSIXly, itu tidak bisa dilakukan
sed
kecuali dengan menyediakan set lengkap surat yang ingin Anda transliterasikan seperti yang ditunjukkan oleh @cuonglm .Itu bisa dilakukan dengan
tr
, dan itutr
untuk (transliterate):Namun, di Linux, ada batasannya. Dari 3
tr
implementasi yang biasa ditemukan pada sistem berbasis Linux:tr
, yang hanya berfungsi untuk set karakter byte tunggal. Misalnya, diStéphane Chazelas
dalam lokal UTF-8, yang memberisTéPHANE cHAZELAS
bukansTÉPHANE cHAZELAS
. Itu adalah keterbatasan GNUtr
.tr
dari toolchest heirloom, itu tidak berhasil (Anda dapatkanstéphane chazelas
).tr
.Pada FreeBSD itu berfungsi dengan baik. Anda akan mengharapkannya berfungsi dengan baik di sistem Unix bersertifikat juga.
The
bash
shell memiliki operator khusus untuk itu:Dengan
zsh -o extendedglob
:sumber
ⴠ
(e2 b4 a0) adalahჀ
(e1 83 80); baiki
(69) danı
(c4 b1) memilikiI
(49) sebagai huruf besar (kecuali di lokal Turki di manai
menjadiİ
). Alasan tidak bekerja dengan GNUtr
adalah karena GNUtr
bekerja dengan byte dan bukan karakter.[:lower:]
atau[:upper:]
(jadi yang pertama diabaikan). Bahkan di Perancis,œ -> Œ
adalahc5 93 -> c5 92
dalam UTF-8 danbd -> bc
di iso8859-15.Meskipun ini memiliki keterbatasan yang sama yang telah disebutkan sebagai
tr
solusi yang ditawarkan oleh Stéphane Chazelas, ini adalah cara lain untuk melakukannya:KELUARAN
Saya membuang
stderr
ke/dev/null
sana karenadd
juga menyediakan statistik dari semua operasinya pada2
deskriptor file. Ini bisa bermanfaat tergantung pada apa yang Anda lakukan, tetapi tidak untuk demonstrasi ini. Semua hal lain yang dapat Anda lakukandd
masih berlaku, misalnya:KELUARAN:
sumber
aBc
tidak dikonversi keAbC
).Jika tujuan utama Anda adalah untuk mengkonversi file dari kelas bawah ke kelas atas, mengapa tidak Anda gunakan
tr
danSTDOUT
untuk mengkonversi file Anda:Di mana
FILENAME
file asli Anda. Di manaFILENAME2
file hasil konversi Anda.sumber
é
misalnya (setidaknya dalam file saya).menggunakan
awk
:sumber
>file.txt
akan memulai dengan memotong fileruby
memiliki metode string untuk itu, penggunaan yang serupa dari baris perintah sepertiperl
Lihat juga Encoding ruby-doc
sumber
Buat hal yang sederhana tetap sederhana. Filter yang dirancang untuk menerjemahkan karakter adalah
tr
.sumber