วิธีการจับคู่ช่องว่างใน sed?


218

ฉันจะจับคู่ whitespace ใน sed ได้อย่างไร ในข้อมูลของฉันฉันต้องการจับคู่ช่องว่างที่ตามมาทั้งหมด 3 ตัว (ช่องว่างแท็บ) และแทนที่ด้วยช่องว่าง 2 ช่อง สิ่งนี้สามารถทำได้?

คำตอบ:


226

ชั้นเรียนตัวอักษร\sจะตรงกับตัวละครช่องว่างและ<tab><space>

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

$ sed -e "s/\s\{3,\}/  /g" inputFile

จะแทนที่ทุกลำดับอย่างน้อย 3 ช่องว่างด้วยสองช่องว่าง


หมายเหตุ : สำหรับการปฏิบัติตาม POSIX ให้ใช้คลาสตัวอักษร[[:space:]]แทน\sเนื่องจากตัวต่อท้ายเป็นส่วนขยายของ GNU sed ดูข้อมูลจำเพาะ POSIX สำหรับsedและBRE


5
AHA! มันเป็นสวิตช์ -e ที่หายไปที่ทำให้ฉัน
sequoia mcdowell

25
ฉันยังต้องเพิ่มสวิตช์ '-r' ซึ่งช่วยให้ regex แบบขยายเพื่อให้รู้จัก '\ s' เป็นพื้นที่
HUB

39
ด้วย Apple sedฉันต้องใช้[[:space:]]เพราะ\sไม่ได้ผลสำหรับฉัน อาจ\sจะเป็นส่วนขยายsed GNU ?
Jared Beck

2
@ JaredBeck ขอบคุณฉันไม่มีความคิดว่าเพราะเหตุใด regex ธรรมดาของฉันจึงไม่ทำงาน .. นี่มันง่อยฉันคิดว่า \ s เป็น regex มาตรฐานที่เพิ่มขึ้น .. นอกจากนี้ - r ไม่ทำงานและ -E ไม่ได้หมอบ
Karthik T

3
แทนที่จะใช้[[:space:]อย่างใดอย่างหนึ่งก็สามารถใช้[[:blank:]]ซึ่งจะจับคู่แท็บแนวนอนและช่องว่างเท่านั้น (แต่ไม่มีบรรทัดใหม่แท็บแนวตั้ง ฯลฯ )
stefanct

67

ใช้งานได้กับ MacOS 10.8:

sed -E "s/[[:space:]]+/ /g"

2
คุณรู้หรือไม่ว่าสิ่งนี้ใช้ได้กับ Linux distros ทั้งหมดหรือไม่
สัตว์สะเทินน้ำสะเทินบก

2
โดยทั่วไปแล้วGNU sedจะไม่มี -E จากหน้า BSD sed man: "ตัวเลือก -E, -a และ -i เป็นส่วนเสริม FreeBSD ที่ไม่ได้มาตรฐานและอาจไม่สามารถใช้ได้กับระบบปฏิบัติการอื่น"
แบรดโคช์

1
ทำไมคุณต้องใช้แฟล็ก -E สำหรับโอเปอเรเตอร์ + นิพจน์ส่วนใหญ่น่าจะใช้ได้ดีกับ * แทนดังนั้นสิ่งนี้จะใช้ได้กับแพลตฟอร์มอื่น
ซามูเอล

5
@Samuel ถ้าคุณใช้ * regex จะจับคู่เว้นวรรคเป็นศูนย์หรือมากกว่านั้นและคุณจะได้ช่องว่างระหว่างตัวละครทุกตัวและช่องว่างที่ปลายแต่ละด้านของแต่ละบรรทัด หากคุณไม่มีแฟล็ก -E คุณต้องการsed "s/[[:space:]]\+/ /g"จับคู่หนึ่งช่องว่างหรือมากกว่า
jbo5112

1
FWIW ผู้สนับสนุนของ NetBSD สนับสนุนการ-Eตั้งค่าสถานะเช่นกัน
mcandre

13

sed รุ่นเก่าบางรุ่นอาจไม่รู้จัก \ s เป็นโทเค็น white space ที่ตรงกับ ในกรณีนี้คุณสามารถจับคู่ลำดับของช่องว่างและแท็บอย่างน้อยหนึ่งรายการกับ '[XZ] [XZ] *' โดยที่ X คือช่องว่างและ Z คือแท็บ


1
ดังนั้นสำหรับความต้องการเฉพาะที่นี่ด้วย sed รุ่นเก่าคุณสามารถทำได้: $ sed 's / [XZ] [XZ] [XZ] [XZ] * / / g' inputfile โดยที่ X คือแท็บและ Z เป็นช่องว่าง
Marnix A. van Ammers

10
sed 's/[ \t]*/"space or tab"/'

2
สิ่งนี้รับประกันได้หรือไม่ว่าจะใช้sedกับระบบรุ่นใด ๆ ถ้าไม่ใช่มันอาจจะคุ้มค่าที่จะกล่าวถึงว่ามันทำงานอย่างไรในลักษณะเดียวกันกับคำตอบอื่น ๆ ดังนั้นเราจึงรู้ถึงข้อ จำกัด และตำแหน่งที่อาจไม่มีผลลัพธ์ตามที่ตั้งใจไว้
Mokubai

2
RE นี้คือสิ่งที่ฉันใช้เพื่อจับคู่กับช่องว่าง มันง่ายกว่าคลาสอักขระเพียงเพื่อจับคู่แท็บหรือช่องว่าง มันใช้เฉพาะการประชุมพื้นฐานที่สุดของการแสดงออกปกติดังนั้นมันควรจะทำงานได้ทุกที่ด้วยการใช้งานการทำงานของการแสดงออกปกติ
เนท

3
สำหรับ Mac 10.9.5 การจับคู่นี้สำหรับช่องว่างและ 't' ฉันใช้ Michael Douma ด้านบนเพื่อจับคู่ตัวอักษรในช่องว่าง (มันใช้ได้กับ -e)
Alien Life Form

ไม่ทำงานอย่างสมเหตุสมผลบนระบบ SUSE ของฉัน มันตรงกับสถานที่แรกในบรรทัดที่มีศูนย์หรือมากกว่าช่องว่างซึ่งอยู่ก่อนตัวอักษรตัวแรก ฉันสงสัยว่าเป็นฟังก์ชั่นที่ตั้งใจและแน่นอนว่าไม่ใช่กรณีการใช้งานที่ร้องขอ ฉันเชื่อว่าคุณต้องการเปลี่ยน '*' สำหรับ '\ +' (หรือ '\ {3, \}' ต่อคำถาม) และอาจวาง ag ที่ส่วนท้ายของคำสั่ง sed เพื่อให้ตรงกับรูปแบบที่เกิดขึ้นทั้งหมด การแทนที่ [\ t] ด้วย [[: space:]] ก็อาจเป็นที่ต้องการเช่นกันในกรณีที่มีสิ่งอื่นสำหรับช่องว่างในบรรทัด
jbo5112
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.