คำสั่งcut
มีตัวเลือกในการทำงานกับตัวละครแทนของไบต์ที่มีตัวเลือก-c
-b
แต่ดูเหมือนจะไม่ทำงานในen_US.UTF-8
สถานที่:
ไบต์ที่สองให้อักขระ ASCII ตัวที่สอง (ซึ่งเข้ารหัสเหมือนกันใน UTF-8):
$ printf 'ABC' | cut -b 2
B
แต่ไม่ได้ให้อักขระที่สองในสามของอักขระที่ไม่ใช่ ASCII กรีกในโลแคล UTF-8:
$ printf 'αβγ' | cut -b 2
�
ว่าไม่เป็นไร - เป็นที่สองไบต์
ดังนั้นเรามองไปที่ตัวละครที่สองแทน:
$ printf 'αβγ' | cut -c 2
�
ดูหัก
ด้วยการทดลองบางอย่างปรากฎว่าช่วง3-4
แสดงตัวละครที่สอง:
$ printf 'αβγ' | cut -c 3-4
β
แต่นั่นก็เหมือนกับไบต์ 3 ถึง 4:
$ printf 'αβγ' | cut -b 3-4
β
ดังนั้น-c
ไม่เกิน-b
UTF-8
ฉันคาดว่าการตั้งค่าภาษาจะไม่เหมาะสมสำหรับ UTF-8 แต่ในการเปรียบเทียบwc
ทำงานได้ตามที่คาดไว้
มันมักจะใช้ในการนับไบต์ด้วยตัวเลือก-c
( --bytes
)
(สังเกตชื่อตัวเลือกที่สับสน)
$ printf 'αβγ' | wc -c
6
แต่ก็สามารถนับตัวอักษรด้วยตัวเลือก-m
( --chars
) ซึ่งใช้งานได้:
$ printf 'αβγ' | wc -m
3
ดังนั้นการกำหนดค่าของฉันดูเหมือนว่าจะเป็น OK - cut
แต่สิ่งที่เป็นเรื่องเกี่ยวกับพิเศษ
อาจจะไม่รองรับ UTF-8 เลยเหรอ? แต่ก็ไม่ดูเหมือนจะสนับสนุนอักขระหลายไบต์มิฉะนั้นก็จะไม่จำเป็นต้องให้การสนับสนุนและ-b
-c
แล้วมีอะไรผิดปกติ? และทำไม?
การตั้งค่าโลแคลนั้นเหมาะสมสำหรับ utf8 เท่าที่ฉันจะบอกได้:
$ 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=
อินพุตไบต์ต่อไบต์:
$ printf 'αβγ' | hd
00000000 ce b1 ce b2 ce b3 |......|
00000006
-c
-b
คุณได้ดูซอร์สโค้ดหรือไม่? บางทีคุณอาจพบคำใบ้ว่าสิ่งที่-c
มีความหมายสำหรับ