วิธีแปลงไฟล์ UTF-8 txt ไปเป็นตัวพิมพ์ใหญ่ทั้งหมดใน bash?


10

ฉันมีไฟล์ UTF-8 .txt บางไฟล์ซึ่งฉันต้องการแปลงเป็นตัวพิมพ์ใหญ่ทั้งหมด หากเป็นเพียง ASCII ฉันสามารถใช้:

tr [:lower:] [:upper:]

แต่เนื่องจากฉันทำงานกับกำกับกำกับและเนื้อหามันจึงไม่ทำงาน ฉันเดาว่าอาจใช้งานได้หากฉันตั้งค่าภาษาที่เหมาะสม แต่ฉันต้องการให้สคริปต์นี้พกพาได้

คำตอบ:


14

ทั้งหมดของ:

tr '[:lower:]' '[:upper:]'

(อย่าลืมคำพูดที่อื่นที่จะไม่ทำงานถ้ามีไฟล์ที่เรียกว่า:, l... หรือrในไดเรกทอรีปัจจุบัน) หรือ:

awk '{print toupper($0)}'

หรือ:

dd conv=ucase

มีวัตถุประสงค์เพื่อแปลงอักขระเป็นตัวพิมพ์ใหญ่ตามกฎที่กำหนดไว้ในโลแคลปัจจุบัน อย่างไรก็ตามแม้ที่โลแคลใช้ UTF-8 เป็นชุดอักขระและกำหนดการแปลงอย่างชัดเจนจากตัวพิมพ์เล็กเป็นตัวพิมพ์ใหญ่อย่างน้อย GNU dd, GNU trและmawk(ค่าเริ่มต้นawkบน Ubuntu เป็นต้น) ไม่ปฏิบัติตาม นอกจากนี้ยังไม่มีวิธีมาตรฐานในการระบุสถานที่อื่นนอกเหนือจากCหรือPOSIXดังนั้นหากคุณต้องการแปลงไฟล์ UTF-8 ให้เป็นตัวพิมพ์ใหญ่แบบพกพาโดยไม่คำนึงถึงสถานที่ปัจจุบันคุณไม่มีโชคกับเครื่องมือมาตรฐาน

บ่อยครั้งสำหรับการพกพาทางออกที่ดีที่สุดของคุณอาจเป็น Perl:

$ echo lľsšcčtťzž | PERLIO=:utf8 perl -pe '$_=uc'
LĽSŠCČTŤZŽ

ตอนนี้คุณต้องระวังว่าไม่ใช่ทุกคนที่เห็นด้วยกับตัวอักษรที่เป็นตัวพิมพ์ใหญ่

ตัวอย่างเช่นในโลแคลภาษาตุรกีตัวพิมพ์ใหญ่iไม่ใช่Iแต่İ( <U0130>) ที่นี่พร้อมกับมรดกสืบทอดเครื่องมือtrแทนที่จะเป็น GNU tr:

$ echo ií | LC_ALL=C.UTF-8 tr '[:lower:]' '[:upper:]'
IÍ
$ echo ií | LC_ALL=tr_TR.UTF-8 tr '[:lower:]' '[:upper:]'
İÍ

ในระบบของฉันการperlแปลงจากด้านบนถูกกำหนดไว้/usr/share/perl/5.14/unicore/To/Upper.plและฉันพบว่ามันมีพฤติกรรมที่แตกต่างกันไปในอักขระบางตัวจาก GNU libc toupper()ในC.UTF8โลแคลเป็นต้นซึ่งperlมีความแม่นยำมากกว่า ยกตัวอย่างเช่นperlแปลงɀถึงcorrectlyอย่างถูกต้องGNU libc (2.17) จะไม่ทำเช่นนั้น


สำหรับสิ่งที่คุ้มค่าฉันกำลังทำงานกับตัวอักษรเช็ก (และตัวอย่างที่คุณใช้จริง ๆ แล้วเป็นภาษาสโลวัก) ซึ่งตัวอักษรตัวพิมพ์ใหญ่ทั้งหมดจะถูกกำหนดไว้อย่างชัดเจน แต่ชุดภาษาอาจเป็น C ไม่ใช่ภาษาเช็ก Perl ถูกใช้ไปแล้วใน toolchain นี้ดังนั้นการเพิ่มการใช้อื่นอาจไม่เลวร้ายนัก ขอบคุณสำหรับคำอธิบายโดยละเอียด btw!
VPeric

3

ฉันคิดว่าคุณสามารถทำได้ด้วยawkและtoupperฟังก์ชั่นของมัน

ตัวอย่างเช่น

ไม่ทำงานกับ GNU tr:

$ echo lľsšcčtťzž | tr '[:lower:]' '[:upper:]'
LľSšCčTťZž

ทำงานร่วมกับ GNU awk:

$ echo lľsšcčtťzž | awk '{ print toupper($0) }'
LĽSŠCČTŤZŽ

@StephaneChazelas - ขอบคุณฉันเปลี่ยนตัวอย่างความล้มเหลว
slm

ที่ขึ้นอยู่กับสถานที่ปัจจุบันและในtrหรือawkการดำเนินงาน ตัวอย่างเช่นส่วนใหญ่trจะแปลงอักขระอย่างถูกต้องเมื่ออยู่ในโลแคล UTF8 ตามตำแหน่งที่ตั้งปัจจุบัน GNU trไม่ mawkไม่
Stéphane Chazelas

1
ที่จริงแล้วใน FreeBSD (9.1) เป็นอีกทางหนึ่ง มันใช้งานtrได้ แต่ไม่ใช่กับawk
Stéphane Chazelas

@StephaneChazelas - ฉันไม่เชี่ยวชาญในความแปรปรวน 8-) ใครบางคนเพิ่งลงคะแนนสงสัยว่าทำไม
slm

2

งานนี้กับ OS X ของtrแต่ไม่ได้มี GNU tr:

tr '[:lower:]' '[:upper:]'

สิ่งนี้ใช้ได้กับgawkแต่ไม่ใช่กับmawkหรือnawk(ซึ่งอยู่/usr/bin/awkใน OS X):

awk '{print toupper($0)}'

ตัวเลือกอื่นคือใช้ GNU sed:

sed 's/./\u&/g'

ใน Bash 4.0 และใหม่กว่าคุณสามารถใช้การ^^ขยายพารามิเตอร์ได้:

while IFS= read -r l;do printf %s\\n "${l^^}";done
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.