คำถามของฉันคือฉันจะแปลงข้อความทั้งหมดจากตัวพิมพ์ใหญ่เป็นตัวพิมพ์เล็กและในทางกลับกันได้อย่างไร นั่นคือการเปลี่ยนแปลงกรณีของตัวอักษรทั้งหมด มันจะต้องมีการsed
เปลี่ยนอย่างใด
คำถามของฉันคือฉันจะแปลงข้อความทั้งหมดจากตัวพิมพ์ใหญ่เป็นตัวพิมพ์เล็กและในทางกลับกันได้อย่างไร นั่นคือการเปลี่ยนแปลงกรณีของตัวอักษรทั้งหมด มันจะต้องมีการsed
เปลี่ยนอย่างใด
คำตอบ:
นี่คือวิธีตรงในsed
:
$ echo qWeRtY | sed -e 'y/abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ/ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz/'
QwErTy
หรือวิธีที่สั้นกว่ากับ GNU sed
การทำงานกับอักขระใด ๆ ที่มีตัวแปลงเล็ก <-> ตัวพิมพ์ใหญ่ในภาษาของคุณ:
$ echo qWeRtY | sed -E 's/([[:lower:]])|([[:upper:]])/\U\1\L\2/g'
QwErTy
หากคุณสามารถใช้เครื่องมืออื่นเช่น:
perl
(จำกัด ตัวอักษร ASCII):
$ echo qWeRtY | perl -pe 'y/[a-z][A-Z]/[A-Z][a-z]/'
QwErTy
perl
(ให้เป็นปกติมากกว่านี้):
$ echo 'αΒγ' | perl -Mopen=locale -pe 's/(\p{Ll})|(\p{Lu})/uc($1).lc($2)/ge'
ΑβΓ
sed
และตัวพิมพ์สำรองในอินพุต ใช้sed -re 's/([[:lower:]]?)([[:upper:]]?)/\U\1\L\2/g'
แทน (ยังคง GNU เฉพาะ) ตัวแรกจะแปลงตัวอักษรละติน 26 ASCII เพียงตัวเดียวในขณะที่ตัวที่สองจะแปลงตัวอักษรใด ๆ ที่เป็นที่ยอมรับโดยสถานที่ของคุณ สิ่งที่tr
เหมาะสมใน ASCII locales เท่านั้น perl
หนึ่งทำงานเฉพาะสำหรับตัวอักษรละติน ASCII
POSIXly ที่ไม่สามารถทำได้ด้วยการsed
ยกเว้นโดยการให้ชุดที่สมบูรณ์ของตัวอักษรที่คุณต้องการในการแปลเป็น@cuonglm ได้แสดงให้เห็น
มันสามารถทำได้ด้วยtr
และนั่นคือสิ่งที่tr
มีไว้สำหรับ (นักแปล):
tr '[:lower:][:upper:]' '[:upper:][:lower:]'
อย่างไรก็ตามบน Linux มันมีข้อ จำกัด จาก 3 tr
การใช้งานที่พบได้ทั่วไปบนระบบที่ใช้ Linux:
tr
ที่ใช้งานได้กับชุดอักขระไบต์เดียวเท่านั้น ยกตัวอย่างเช่นในStéphane Chazelas
UTF-8 สถานที่ให้แทนsTéPHANE cHAZELAS
sTÉPHANE cHAZELAS
นั่นเป็นข้อ จำกัด ที่เป็นที่รู้จักของ tr
GNUtr
จากเครื่องมือมรดกสืบทอดที่ไม่ทำงาน (คุณได้รับstéphane chazelas
)tr
จะทำกับผู้ใช้งานบน FreeBSD ที่ใช้งานได้ดี คุณคาดหวังว่ามันจะทำงานได้ดีในระบบ Unix ที่ได้รับการรับรองเช่นกัน
bash
เปลือกมีผู้ประกอบการเฉพาะสำหรับว่า:
in=AbCdE
out=${in~~}
ด้วยzsh -o extendedglob
:
out=${in//(#b)(([[:lower:]])|([[:upper:]]))/${(U)match[2]}${(L)match[3]}}
ⴠ
(e2 b4 a0) คือჀ
(e1 83 80) ทั้งi
(69) และı
(c4 b1) มีI
(49) เป็นตัวพิมพ์ใหญ่ (ยกเว้นในที่ตั้งภาษาตุรกีที่i
กลายเป็นİ
) เหตุผลที่มันใช้ไม่ได้กับ GNU tr
ก็คือ GNU นั้นใช้tr
งานได้กับไบต์และไม่ใช่ตัวอักษร
[:lower:]
หรือ[:upper:]
(ดังนั้นรายการแรกจะถูกละเว้น) แม้แต่ในภาษาฝรั่งเศสœ -> Œ
ก็อยู่c5 93 -> c5 92
ใน UTF-8 และbd -> bc
ใน iso8859-15
แม้ว่านี่จะมีข้อ จำกัด เช่นเดียวกันกับที่กล่าวไว้แล้วว่าเป็นtr
วิธีการแก้ปัญหาที่นำเสนอโดยStéphane Chazelas แต่ก็เป็นอีกวิธีที่จะทำได้:
{ echo QWERTYqwerty | dd conv=lcase
echo QWERTYqwerty | dd conv=ucase
} 2>/dev/null
qwertyqwerty
QWERTYQWERTY
ฉันถ่ายโอนstderr
ไปที่/dev/null
นั่นเพราะdd
ยังให้สถิติของการดำเนินงานทั้งหมดใน2
file descriptor สิ่งนี้มีประโยชน์ขึ้นอยู่กับสิ่งที่คุณทำ แต่ไม่ใช่สำหรับการสาธิตนี้ สิ่งอื่น ๆ ทั้งหมดที่คุณสามารถทำได้กับdd
ยังใช้เช่น:
echo QWERTYqwerty | dd bs=1 cbs=6 conv=unblock,ucase 2>/dev/null
QWERTY
QWERTY
aBc
จะไม่ถูกแปลงเป็นAbC
)
หากวัตถุประสงค์หลักของคุณคือการแปลงไฟล์จากคลาสที่ต่ำกว่าเป็นตัวพิมพ์ใหญ่ทำไมคุณไม่ใช้tr
และSTDOUT
แปลงไฟล์ของคุณ:
$cat FILENAME | tr a-z A-Z > FILENAME2
FILENAME
ไฟล์ต้นฉบับของคุณอยู่ที่ไหน FILENAME2
ไฟล์เอาต์พุตที่แปลงแล้วของคุณอยู่ที่ไหน
é
เช่น (อย่างน้อยในไฟล์ของฉัน)
ใช้awk
:
awk '{print tolower($0)}' file.txt | tee file.txt
>file.txt
จะเริ่มต้นด้วยการตัดทอนไฟล์
ruby
มีวิธีสตริงสำหรับการใช้งานที่คล้ายกันจากบรรทัดคำสั่งเช่น perl
$ echo 'qWeRtY' | ruby -pe '$_.swapcase!'
QwErTy
ดูเพิ่มเติมที่การเข้ารหัสทับทิม doc
$ ruby -e 'puts Encoding.default_external'
UTF-8
$ echo 'αΒγ' | ruby -pe '$_.swapcase!'
ΑβΓ
ทำสิ่งที่ง่ายง่าย ๆ tr
ตัวกรองที่ออกแบบมาเพื่อแปลเป็นตัวอักษร
echo 1ude1UDE | tr [:upper:][:lower:] [:lower:][:upper:]
tr
sed
จะเหมาะสมกว่า