sed one-liner เพื่อแปลงตัวพิมพ์ใหญ่ทั้งหมดเป็นตัวพิมพ์เล็ก?


131

ฉันมีไฟล์ข้อความที่มีบางคำพิมพ์เป็นตัวพิมพ์ใหญ่ทั้งหมด ฉันต้องการเพียงแค่แปลงทุกอย่างในไฟล์ข้อความเป็นตัวพิมพ์เล็กโดยใช้sed. นั่นหมายความว่าประโยคแรกจะอ่านว่า 'ฉันมีไฟล์ข้อความที่มีบางคำพิมพ์ด้วยตัวพิมพ์ใหญ่ทั้งหมด'


6
คุณรู้trคำสั่งหรือไม่ sedบางครั้งก็เหมาะสมกว่า
Bryan Oakley

@ ไบรอัน Oakley ตอนนี้ผมยังไม่ถึง ขอบคุณที่ชี้ให้เห็น แต่ฉันจะใช้มันเพื่อทำสิ่งที่ฉันขอได้อย่างไร?
สนามแม่เหล็ก

ดูในลิงค์ที่ให้ไว้ในคำตอบของ Raghuram
Bryan Oakley

1
ถ้าคุณต้องใช้ sed แมว <input> | sed 'y / ABCDEFÑØÅÆŒ / abcdefñøåæœ /' <- คุณต้องลงรายละเอียดอักขระทั้งหมดตัวพิมพ์ใหญ่เป็นตัวพิมพ์เล็ก ฉันรู้ว่ามันยุ่งยากในการเขียนอักขระเหล่านั้นทั้งหมด แต่มันก็ใช้ได้กับอักขระพิเศษระหว่างประเทศเหล่านั้นด้วย :)
Arno Teigseth

คำตอบ:


248

ด้วยtr:

# Converts upper to lower case 
$ tr '[:upper:]' '[:lower:]' < input.txt > output.txt

# Converts lower to upper case
$ tr '[:lower:]' '[:upper:]' < input.txt > output.txt

ทำงานโดยใช้ GNU sed(BSD sedไม่รองรับ\L \U):

# Converts upper to lower case
$ sed -e 's/\(.*\)/\L\1/' input.txt > output.txt

# Converts lower to upper case
$ sed -e 's/\(.*\)/\U\1/' input.txt > output.txt

6
ฉันต้องเลือกคำตอบของตัวเองเพราะฉันไม่ใช่แฟนของคำตอบที่ประกอบด้วยลิงก์
สนามแม่เหล็ก

6
OSX ไม่รองรับส่วนขยาย GNU เช่นกัน :(
ekkis

2
sed -e 's/.*/\L&/' input.txt > output.txtสำหรับ GNU sed ก็ใช้ได้เช่นกัน
Asfand Qazi

1
@ekkis OSX ใช้ BSD (ดังที่กล่าวไว้ BSD sed ไม่รองรับ) ลองอ่านบรรทัดบนสุดman sedเพื่อดูว่าคุณกำลังใช้เวอร์ชันใดอยู่
Ryder

ด้วยเหตุผลบางอย่างเมื่อฉันใช้รูปแบบตัวพิมพ์ใหญ่ของคุณมันจะเพิ่มUด้านหน้าของทุกบรรทัด
Xtremefaith

51

หากคุณมีส่วนขยาย GNU คุณสามารถใช้ \ L ของ sed (ลดการจับคู่ทั้งหมดหรือจนกว่าจะถึง \ L [ต่ำกว่า] หรือ \ E [สิ้นสุด - สลับปลอก]) ดังนี้:

sed 's/.*/\L&/' <input >output

หมายเหตุ: '&' หมายถึงรูปแบบการจับคู่แบบเต็ม

ตามหมายเหตุด้านข้างส่วนขยาย GNU ได้แก่ \ U (upper), \ u (อักขระถัดไปของการจับคู่), \ l (อักขระถัดไปที่ต่ำกว่าของการจับคู่) ตัวอย่างเช่นหากคุณต้องการอูฐประโยค:

$ sed -r 's/\w+/\u&/g' <<< "Now is the time for all good men..." # Camel Case
Now Is The Time For All Good Men...

หมายเหตุ: เนื่องจากสมมติฐานคือเรามีส่วนขยาย GNU เราจึงสามารถใช้ตัวเลือก dash-r (นิพจน์ทั่วไปแบบขยาย) ซึ่งอนุญาตให้ \ w (อักขระคำ) และช่วยให้คุณไม่ต้องหนีจากวงเล็บที่จับและหนึ่งหรือมากกว่า ตัวระบุ (+) (นอกเหนือ: \W [non-word], \s [whitespace], \S [non-whitespace]ได้รับการสนับสนุนกับเส้นประ-R แต่\d [digit]และ\D [non-digit]ไม่ได้.)


1
เคล็ดลับที่มีประโยชน์มาก ฉันพบว่าไม่จำเป็นต้องใช้วงเล็บกลมในตัวอย่างเคสอูฐ 's / \ w + / \ u & / g' ก็ใช้ได้เช่นกัน
PJ_Finnegan

1
sed -ri 's/MATCH_WHATEVER/\L&/i' input-file.ext- การใช้/iตัวปรับแต่งทำให้การจับคู่ไม่คำนึงถึงตัวพิมพ์เล็กและใหญ่จึงเป็นทางเลือก -iสวิทช์บอก sed ที่จะปรับเปลี่ยนไฟล์ในสถานที่ ไม่จำเป็นต้องเปลี่ยนเส้นทางเอาต์พุตไปยังไฟล์อื่นหากคุณไม่จำเป็นต้อง
จิม

1
\E [end - toggle casing off]ผมจำเป็นต้องมีนี้จริงๆ ขอบคุณ !
Mehdi Yedes

37

คุณสามารถทำได้อย่างง่ายดายด้วยawkหากคุณต้องการพิจารณาเครื่องมืออื่น:

echo "UPPER" | awk '{print tolower($0)}'

1
คำตอบที่ดีที่สุดเพราะทำงานร่วมกับซิริลลิก tr: - ไม่ได้ผลกับมัน
Amaroc

2
ระวังอักขระที่มีสำเนียง tolowerไม่สามารถจัดการได้Àเช่น
Sam Houston

คุณสามารถเปลี่ยนชื่อไฟล์จำนวนมากด้วยคำสั่งนั้น: ls | awk '{print "mv " $0 " " tolower($0)}' | sh
Neekobus

15

นี่คือวิธีแก้ปัญหามากมาย:

เพื่ออัพเซอร์เซอร์ด้วย perl, tr, sed และ awk

perl -ne 'print uc'
perl -npe '$_=uc'
perl -npe 'tr/[a-z]/[A-Z]/'
perl -npe 'tr/a-z/A-Z/'
tr '[a-z]' '[A-Z]'
sed y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/
sed 's/\([a-z]\)/\U\1/g'
sed 's/.*/\U&/'
awk '{print toupper($0)}'

พิมพ์เล็กด้วย perl, tr, sed และ awk

perl -ne 'print lc'
perl -npe '$_=lc'
perl -npe 'tr/[A-Z]/[a-z]/'
perl -npe 'tr/A-Z/a-z/'
tr '[A-Z]' '[a-z]'
sed y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/
sed 's/\([A-Z]\)/\L\1/g'
sed 's/.*/\L&/'
awk '{print tolower($0)}'

ทุบตีที่ซับซ้อนเป็นตัวพิมพ์เล็ก:

while read v;do v=${v//A/a};v=${v//B/b};v=${v//C/c};v=${v//D/d};v=${v//E/e};v=${v//F/f};v=${v//G/g};v=${v//H/h};v=${v//I/i};v=${v//J/j};v=${v//K/k};v=${v//L/l};v=${v//M/m};v=${v//N/n};v=${v//O/o};v=${v//P/p};v=${v//Q/q};v=${v//R/r};v=${v//S/s};v=${v//T/t};v=${v//U/u};v=${v//V/v};v=${v//W/w};v=${v//X/x};v=${v//Y/y};v=${v//Z/z};echo "$v";done

ทุบตีที่ซับซ้อนเป็นตัวพิมพ์ใหญ่:

while read v;do v=${v//a/A};v=${v//b/B};v=${v//c/C};v=${v//d/D};v=${v//e/E};v=${v//f/F};v=${v//g/G};v=${v//h/H};v=${v//i/I};v=${v//j/J};v=${v//k/K};v=${v//l/L};v=${v//m/M};v=${v//n/N};v=${v//o/O};v=${v//p/P};v=${v//q/Q};v=${v//r/R};v=${v//s/S};v=${v//t/T};v=${v//u/U};v=${v//v/V};v=${v//w/W};v=${v//x/X};v=${v//y/Y};v=${v//z/Z};echo "$v";done

ทุบตีง่ายๆเป็นตัวพิมพ์เล็ก:

while read v;do echo "${v,,}"; done

ทุบตีง่าย ๆ เป็นตัวพิมพ์ใหญ่:

while read v;do echo "${v^^}"; done

โปรดทราบว่า $ {v,} และ $ {v ^} จะเปลี่ยนตัวอักษรตัวแรกเท่านั้น

คุณควรใช้วิธีนี้:

(while read v;do echo "${v,,}"; done) < input_file.txt > output_file.txt


5

ฉันชอบคำตอบบางส่วนที่นี่ แต่มีคำสั่ง sed ที่ควรทำเคล็ดลับบนแพลตฟอร์มใด ๆ :

sed 'y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/'

ยังไงก็เข้าใจง่าย และการรู้เกี่ยวกับคำสั่ง y อาจเป็นประโยชน์ในบางครั้ง


2
สิ่งนี้ใช้ไม่ได้กับอักขระสากลโดยพลการ แต่ใช้ได้กับอักขระ ASCII ใน OS / X
emrys57

แน่นอนมันได้งานสำหรับฉัน ฉันต้องยอมรับว่านี่เป็นครั้งแรกที่ฉันใช้คำสั่ง y ขอบคุณ!
monsune

4

หากคุณใช้ posix sed

การเลือกสำหรับกรณีใด ๆ สำหรับรูปแบบ (การแปลงรูปแบบการค้นหาด้วย sed นี้แทนที่จะใช้รูปแบบที่แปลงแล้วในคำสั่งที่คุณต้องการโดยใช้ regex:

echo "${MyOrgPattern} | sed "s/[aA]/[aA]/g;s/[bB]/[bB]/g;s/[cC]/[cC]/g;s/[dD]/[dD]/g;s/[eE]/[eE]/g;s/[fF]/[fF]/g;s/[gG]/[gG]/g;s/[hH]/[hH]/g;s/[iI]/[iI]/g;s/[jJ]/[jJ]/g;s/[kK]/[kK]/g;s/[lL]/[lL]/g;s/[mM]/[mM]/g;s/[nN]/[nN]/g;s/[oO]/[oO]/g;s/[pP]/[pP]/g;s/[qQ]/[qQ]/g;s/[rR]/[rR]/g;s/[sS]/[sS]/g;s/[tT]/[tT]/g;s/[uU]/[uU]/g;s/[vV]/[vV]/g;s/[wW]/[wW]/g;s/[xX]/[xX]/g;s/[yY]/[yY]/g;s/[zZ]/[zZ]/g" | read -c MyNewPattern
 YourInputStreamCommand | egrep "${MyNewPattern}"

แปลงเป็นตัวพิมพ์เล็ก

sed "s/[aA]/a/g;s/[bB]/b/g;s/[cC]/c/g;s/[dD]/d/g;s/[eE]/e/g;s/[fF]/f/g;s/[gG]/g/g;s/[hH]/h/g;s/[iI]/i/g;s/j/[jJ]/g;s/[kK]/k/g;s/[lL]/l/g;s/[mM]/m/g;s/[nN]/n/g;s/[oO]/o/g;s/[pP]/p/g;s/[qQ]/q/g;s/[rR]/r/g;s/[sS]/s/g;s/[tT]/t/g;s/[uU]/u/g;s/[vV]/v/g;s/[wW]/w/g;s/[xX]/x/g;s/[yY]/y/g;s/[zZ]/z/g"

เหมือนกันสำหรับตัวพิมพ์ใหญ่แทนที่ตัวอักษรล่างระหว่าง // โดยเทียบเท่าตัวบนใน sed

มีความสุข


(ฉันพบว่าอันนี้ทำงานได้ดีที่สุดบน MacOS) - ดีเพื่อนของฉัน - แต่โทโปตัวเล็ก ๆ - คุณมีเคส Jj อยู่ข้างหลัง ควรเป็น sed "s / [aA] / a / g; s / [bB] / b / g; s / [cC] / c / g; s / [dD] / d / g; s / [eE] / E / g; s / [FF] / f / g; s / [GG] / g / g; s / [HH] / เอช / g; s / [ii] / i / g; s / [JJ] / J / g; s / [KK] / k / g; s / [LL] / L / g; s / [mm] / m / g; s / [nN] / n / g; s / [oO] / o / g; s / [pP] / p / g; s / [QQ] / q / g; s / [RR] / R / g; s / [SS] / s / g; s / [tT] / T / g; s / [UU] / u / g; s / [VV] / v / กรัม; s / [WW] / w / g; s / [xX] / x / g; s / [yy] / y / g; s / [zZ] / z / g "
Neil McGill

ฉันไม่แน่ใจว่าทำไมคุณต้องทำอะไรที่ต้องใช้แรงงานมากขนาดนี้ ฉันสมมติว่า Mac OS ไม่มีส่วนขยาย GNU แต่ถ้าคุณตายแล้วในการใช้ sed แทนที่จะใช้การแทนที่คุณสามารถใช้การทับศัพท์ ('y') ดังนี้ sed 'y / ABCDEFGHIJKLMNOPQRSTUVWXYZ / abcdefghijklmnopqrstuvwxyz / '
Luv2code

เป้าหมายคือการเลือกรูปแบบข้อความใด ๆ ที่มีลักษณะเป็นตัวพิมพ์เล็ก / ใหญ่จากที่ไม่ใช่ GNU sed โดยไม่เปลี่ยนเนื้อหาของแหล่งข้อมูล ( y//เปลี่ยนเนื้อหาของแหล่งที่มาหรืออาจพลาดการค้นหารูปแบบ
NeronLeVelu

3

สั้นหวานและคุณไม่จำเป็นต้องเปลี่ยนเส้นทาง :-)

perl -p -i -e 'tr/A-Z/a-z/' file

ฮ่า ๆ ฉันพยายามใช้สิ่งนี้โดยดูเบื้องหลังและมันก็แทนที่ตัวอักษรส่วนใหญ่ทั้งหมดในไฟล์ของฉันด้วยตัวอักษรตัวพิมพ์ใหญ่แบบสุ่มอื่น ๆ ทำให้ฉันหัวเราะได้ดีต่อไป ฉันสามารถได้รับสิ่งที่ต้องการจากคำตอบนี้เช่นกันเกี่ยวกับ perl: askubuntu.com/a/527073/250556
ThorSummoner
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.