Konversi isi file menjadi huruf kecil

85

Saya memiliki tempfile dengan konten huruf kecil dan huruf besar.

Memasukkan

Isi tempfile saya :

hi
Jigar
GANDHI
jiga

Saya ingin mengonversi semua atas ke bawah .

Perintah

Saya mencoba perintah berikut:

sed -e "s/[A-Z]/[a-z]/g" temp

tetapi mendapat output yang salah.

Keluaran

Saya menginginkannya sebagai:

hi
jigar
gandhi
jiga

Apa yang perlu di bagian pengganti argumen sed?

JigarGandhi
sumber

Jawaban:

122

Jika input Anda hanya berisi karakter ASCII, Anda dapat menggunakan trseperti:

tr A-Z a-z < input 

atau (kurang mudah diingat dan mengetik IMO; tetapi tidak terbatas pada huruf latin ASCII, meskipun dalam beberapa implementasi termasuk GNU tr, masih terbatas pada karakter byte tunggal, jadi di lokal UTF-8, masih terbatas pada huruf ASCII):

tr '[:upper:]' '[:lower:]' < input

jika Anda harus menggunakan sed:

sed 's/.*/\L&/g' < input

(di sini dengan asumsi implementasi GNU).

Dengan POSIX sed, Anda harus menentukan semua transliterasi dan kemudian Anda dapat memilih huruf mana yang ingin Anda konversi:

sed 'y/AǼBCΓDEFGH.../aǽbcγdefgh.../' < input

Dengan awk:

awk '{print tolower($0)}' < input
Anthon
sumber
3
Harap dicatat bahwa itu \Ladalah ekstensi GNU.
Anthon
\Lbekerja dengan baik untuk saya sejauh ini.
Enlight
2
@JigarGandhi. sedadalah perintah Unix. Sistem yang berbeda memiliki varian yang berbeda dengan perilaku dan fungsi yang berbeda pula. Untungnya, saat ini, ada standar yang paling sesuai sehingga Anda dapat mengandalkan set fitur minimum yang umum untuk semua. \Ltidak ada di antara mereka dan diperkenalkan oleh GNU sed(cocok dengan operator yang sama dalam standar ex/ vi) dan umumnya tidak tersedia dalam implementasi lainnya.
Stéphane Chazelas
9
Perhatikan bahwa beberapa trimplementasi seperti GNU trtidak berfungsi dengan baik di multi-byte locales (kebanyakan dari mereka saat ini, coba echo STÉPHANE | tr '[:upper:]' '[:lower:]'misalnya). Pada sistem GNU, Anda mungkin lebih suka sedvarian atau awk's tolower().
Stéphane Chazelas
5
Koreksi sedikit: sed 's/.*/\L&/g' < input. The \1mengacu pada substring cocok tidak akan bekerja kecuali Anda menentukan substring dengan kurung sebagai wurtle tidak dalam nya. Namun, ini sedikit lebih bersih untuk digunakan &untuk mewakili seluruh pertandingan, seperti yang ditunjukkan
Edward Brown
30

Menggunakan vim, ini sangat sederhana:

$ vim filename
gg0guGZZ

Buka file, ggpergi ke baris 0pertama,, kolom pertama. Dengan guG, menurunkan huruf besar semua karakter hingga bagian bawah file. ZZmenyimpan dan keluar.

Itu harus menangani apa saja yang Anda lemparkan; itu akan mengabaikan angka, itu akan menangani non ASCII.

Jika Anda ingin melakukan yang sebaliknya, mengubah huruf cased kecil menjadi huruf besar, swap ukeluar untuk U: gg0gUGZZdan Anda sudah siap.

TankorSmash
sumber
14
Lol "super sederhana"
blambert
ini jelas tidak skala baik untuk banyak file
Corey Goldberg
jawaban paling favorit saya sejauh ini !!!!
Mona Jalal
1
@CoreyGoldberg vim file1 file2 fileetcdan kemudian sesuatu seperti mungkin:bufdo gg0guG:w<CR> akan berfungsi untuk sejumlah file. Belum diuji itu!
TankorSmash
@TankorSmash yang masih tidak menskala ke sejumlah besar file
Corey Goldberg
17

Saya suka dduntuk ini, saya sendiri.

<<\IN LC_ALL=C 2<>/dev/null \
dd conv=lcase
hi
Jigar 
GANDHI
jiga
IN

...mendapat...

hi
jigar
ghandi
jiga

The LC_ALL=Cadalah untuk melindungi multibytes setiap input - meskipun setiap ibukota multibyte tidak akan dikonversi. Hal yang sama berlaku untuk (GNU) tr - kedua aplikasi cenderung memasukkan mangling di lokal non-C. iconvdapat dikombinasikan dengan solusi komprehensif.

The 2>/dev/nullredirect membuang ddStatus 's laporan default - dan stderr nya. Tanpa itu ddakan mengikuti penyelesaian pekerjaan seperti di atas dengan mencetak informasi seperti berapa byte yang diproses dan lain-lain.

mikeserv
sumber
Solusi ini jauh lebih cepat daripada trsaat menangani file besar, terima kasih!
WhiteWinterWolf
13

Anda juga dapat menggunakan Perl 5:

perl -pe '$_=lc' temp

Opsi -pmemberitahu perl untuk menjalankan ekspresi yang ditentukan satu kali untuk setiap baris input, mencetak hasilnya, yaitu nilai akhir dari $_. -emenunjukkan bahwa program akan menjadi argumen berikutnya, sebagai lawan dari file yang berisi skrip. lcdikonversi ke huruf kecil. Tanpa argumen, itu akan beroperasi $_. Dan $_=menyimpannya lagi sehingga akan dicetak.

Variasi itu akan menjadi

perl -ne 'print lc' temp

Menggunakan -nseperti -pkecuali yang $_tidak akan dicetak pada akhirnya. Jadi alih-alih menyimpan ke variabel itu, saya menyertakan pernyataan cetak eksplisit.

Satu kelebihan Perl berbeda dengan sed adalah Anda tidak memerlukan ekstensi GNU. Ada proyek-proyek yang harus kompatibel dengan lingkungan non-GNU tetapi yang juga sudah memiliki dependensi Perl. Dibandingkan dengan tr, mungkin Perl lcdapat lebih mudah dibuat sadar-lokal. Lihat perllocalehalaman manual untuk detailnya.

MvG
sumber
9

Anda perlu menangkap pola yang cocok dan kemudian menggunakannya dalam penggantian dengan pengubah:

sed 's/\([A-Z]\)/\L\1/g' temp

The \(...\)"menangkap" para melampirkan cocok teks, penangkapan pertama pergi ke \1, di samping \2, dll penomoran ini sesuai dengan membuka kurung dalam kasus menangkap bersarang.

The \Lbertobat pola ditangkap untuk menurunkan kasus, ada juga \Uuntuk kasus atas.

Wurtel
sumber
3
Anda tidak perlu melakukan ini - seluruh pola selalu terperangkap&
mikeserv
Benar, tetapi kemudian saya akan melewatkan kesempatan untuk menjelaskan pertandingan menangkap :-)
wurtel