Perintah cut
memiliki opsi -c
untuk bekerja pada karakter, alih-alih byte dengan opsi -b
. Tapi sepertinya itu tidak berhasil, di en_US.UTF-8
tempat:
Byte kedua memberikan karakter ASCII kedua (yang dikodekan sama di UTF-8):
$ printf 'ABC' | cut -b 2
B
tetapi tidak memberikan karakter kedua dari tiga karakter non-ASCII Yunani di lokal UTF-8:
$ printf 'αβγ' | cut -b 2
�
Tidak apa-apa - ini byte kedua .
Jadi kita melihat karakter kedua sebagai gantinya:
$ printf 'αβγ' | cut -c 2
�
Itu terlihat rusak.
Dengan beberapa percobaan, rentang tersebut 3-4
menunjukkan karakter kedua:
$ printf 'αβγ' | cut -c 3-4
β
Tapi itu sama dengan byte 3 hingga 4:
$ printf 'αβγ' | cut -b 3-4
β
Jadi -c
tidak lebih dari -b
untuk UTF-8.
Saya berharap pengaturan lokal tidak tepat untuk UTF-8, tetapi sebagai perbandingan, wc
berfungsi seperti yang diharapkan;
Ini sering digunakan untuk menghitung byte, dengan opsi -c
( --bytes
).
(Perhatikan nama opsi yang membingungkan.)
$ printf 'αβγ' | wc -c
6
Tetapi juga dapat menghitung karakter dengan opsi -m
( --chars
), yang hanya berfungsi:
$ printf 'αβγ' | wc -m
3
Jadi konfigurasi saya tampaknya ok - tetapi ada sesuatu yang istimewa cut
.
Mungkin tidak mendukung UTF-8 sama sekali? Tetapi tampaknya mendukung karakter multi-byte, jika tidak maka tidak perlu mendukung -b
dan -c
.
Jadi, apa yang salah? Dan mengapa?
Pengaturan lokal terlihat tepat untuk utf8, sejauh yang saya tahu:
$ locale
LANG=en_US.UTF-8
LANGUAGE=en_US
LC_CTYPE=en_US.UTF-8
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_PAPER="en_US.UTF-8"
LC_NAME="en_US.UTF-8"
LC_ADDRESS="en_US.UTF-8"
LC_TELEPHONE="en_US.UTF-8"
LC_MEASUREMENT="en_US.UTF-8"
LC_IDENTIFICATION="en_US.UTF-8"
LC_ALL=
Input, byte demi byte:
$ printf 'αβγ' | hd
00000000 ce b1 ce b2 ce b3 |......|
00000006
sumber
-c
menggunakan kode yang sama dengan-b
. Apakah Anda sudah melihat kode sumbernya? Mungkin Anda bisa menemukan petunjuk untuk apa-c
sebenarnya.Jawaban:
Anda belum mengatakan yang
cut
Anda gunakan, tetapi karena Anda telah menyebutkan opsi panjang GNU--characters
saya akan menganggap itu salah satunya. Dalam hal ini, perhatikan bagianinfo coreutils 'cut invocation'
ini dari :(penekanan ditambahkan)
Untuk saat ini, GNU
cut
selalu bekerja dalam hal "karakter" byte tunggal, sehingga perilaku yang Anda lihat diharapkan.Mendukung opsi
-b
dan diperlukan oleh POSIX - mereka tidak ditambahkan ke GNU karena memiliki dukungan multi-byte dan mereka bekerja dengan baik, tetapi untuk menghindari memberikan kesalahan pada masukan yang sesuai dengan POSIX. Hal yang sama telah dilakukan dalam beberapa implementasi lain , meskipun tidak FreeBSD dan OS X setidaknya.-c
cut
-c
cut
Ini adalah perilaku bersejarah dari
-c
.-b
baru ditambahkan untuk mengambil alih peran byte sehingga-c
dapat bekerja dengan karakter multi-byte. Mungkin dalam beberapa tahun ini akan berfungsi seperti yang diinginkan secara konsisten, meskipun kemajuannya belum cepat (sudah lebih dari satu dekade sudah). GNUcut
bahkan belum mengimplementasikan-n
opsi , meskipun itu ortogonal dan dimaksudkan untuk membantu transisi. Ada potensi masalah kompatibilitas dengan skrip lama, yang mungkin menjadi perhatian, meskipun saya tidak tahu pasti apa alasannya.sumber
tr
dokumen GNU juga. dan bahkantar
kecuali saya salah ingat. Saya kira ini adalah proyek besar.cut
? Misalnya, di mana dimungkinkan untuk mengunduh sumber untuk ditambalcut
? Atau akankah lebih mudah menggunakan utilitas lain? (grep
solusi di bawah ini tidak bekerja dengan baik dengan rentang mis.5-8,44-49
)cut -c
sini: superuser.com/questions/506164/…colrm
(bagian dariutil-linux
, harus sudah diinstal pada sebagian besar distribusi) tampaknya menangani internasionalisasi jauh lebih baik:Waspadalah terhadap penomoran:
colrm N
akan menghapus kolom dariN
, mencetak karakter hinggaN-1
.( kredit )
sumber
Karena banyak
grep
implementasi yang multibyte-sadar, Anda juga dapat menggunakangrep -o
untuk mensimulasikan beberapa penggunaancut -c
.Sesuaikan jumlah periode untuk mensimulasikan
cut
rentang.sumber