การแทนที่จุด (.) เป็น sed


9

ดังนั้นคำถามที่แท้จริงคือ - ไม่มีใครมีความคิดวิธีการลบM-BM-ตัวละครพิเศษโดยไม่เสี่ยงต่อการสูญเสียตัวละครอื่น ๆ ?

ฉันมีข้อความ:

" . . ."

นั่นคือ

space dot space dot space dot

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

"..."

นั่นคือ

dot dot dot

ฉันพยายามจะทำกับ sed:

sed -r 's:\s\.\s\.\s\.:...:g' -i sed-dots

น่าเสียดายที่มันไม่เปลี่ยนไฟล์อินพุตแม้แต่นิดเดียว ไฟล์: https://www.dropbox.com/s/46zmiruy3ln85a1/sed-dots

เมื่อฉันพยายามที่จะแทนที่สตริงเดียวกันใน text editor (ฉันใช้ geany) จะพบและแทนที่อย่างถูกต้อง

เหตุผลเดียวที่ฉันคิดได้ก็คือพื้นที่บางส่วน (หรือทั้งหมด) ไม่ใช่ช่องว่าง แต่เป็นอักขระพิเศษ

ใครบ้างมีความคิดวิธีการค้นหาและแทนที่สตริงนั้นด้วย sed (หรือเครื่องมือบรรทัดคำสั่งอื่น ๆ )? โปรดทดสอบความคิดของคุณในไฟล์ของฉันเนื่องจากปัญหาไม่ชัดเจนเท่าที่ควร - นี่คือสาเหตุที่ฉันถามถึงมัน

หลังจากใช้cat -Amyfile ดูเหมือนว่ามีปัญหาว่าช่องว่างเหล่านั้นไม่ใช่ช่องว่าง แต่M-BM-เป็นอักขระพิเศษ การใช้สัญลักษณ์ใด ๆ ที่.แนะนำสำหรับการค้นหาไม่ใช่ความคิดที่ดีเนื่องจากมีความเสี่ยงที่อักขระอื่น ๆ จะถูกลบออก

คำตอบ:


10

ก่อนอื่นฉันจะเริ่มต้นด้วยการทดสอบechoและการไพพ์นั้นเข้าsedด้วยกันมากกว่าการใช้ไฟล์จริง ประการที่สองคุณสามารถใช้{n}ในโมเดล regex เพิ่มเติมเพื่อแสดงผลคูณและขีด จำกัด

คุณอยู่ที่นั่นสวยมาก แต่ regex ของคุณคาดว่าจะเป็นพื้นที่นำ

$ echo 'cheese . . . muffins' | sed -r 's/(\s?\.){3}/ dot dot dot/g'
cheese dot dot dot muffins

สังเกตว่า\s?ยังคงโลภมากพอที่จะทำลายเอาท์พุทดังนั้นฉันจึงเพิ่มพื้นที่ลงในเอาต์พุต คุณอาจไม่ต้องการที่ ฉันได้กำหนดให้เว้นวรรคด้วยกันดังนั้นมันจะจับคู่กับสิ่งต่อไปนี้ทั้งหมด:

...
. ..
.. .
. . .
 . . . 

เพียงแค่ลบ?ธงเสริม


ให้ปัญหาของคุณกับยูนิโค้ด (ในความคิดเห็น) คุณสามารถบังคับข้อมูลให้เทียบเท่ากับ ASCII ของมันiconvแล้วติดมัน:

$ iconv -f utf-8 -t ascii//translit sed-dots | sed -r 's/(\s?\.){3}/ dot dot dot/g'
Lorem ipsum dot dot dot
Some dot dot dot more text

ฉันประหลาดใจที่คุณแนะนำให้ใช้echoแทนการปล่อยไฟล์อย่างน้อยที่สุดเมื่อคุณ cat ไฟล์คุณรู้ว่าเชลล์ไม่ได้ตีความอะไรเลยและไม่มีเสียงก้อง
Flimm

@Flimm สำหรับตัวอย่างง่ายๆที่มีจุดนี่ไม่ใช่ปัญหาจริงๆ หากคุณกำลังจะโหลดจากไฟล์อย่ากังวลcat- เพียงแค่sedโหลดไฟล์ (ตามตัวอย่างของ OP) แต่อย่าบันทึก inline (ลบ-iเพื่อให้คุณสามารถดูและทดสอบกับเอาต์พุต)
Oli

@Oli มันทำงานกับตัวอย่างของคุณ แต่มันไม่ทำงานกับไฟล์ของฉัน (ในคำถามของฉันมีลิงก์) นั่นคือปัญหา - คำสั่งของคุณและคนอื่น ๆ ควรจะทำงานได้ แต่มันก็ไม่เป็นเช่นนั้นเพราะปัญหาบางอย่างกับจุดเหล่านั้น โปรดทดสอบคำสั่งของคุณในไฟล์ของฉันและคุณจะเห็นว่ามันไม่ทำงาน
Rafal

1
@Rafal ถ้าคุณดูcat -A sed-dotsคุณจะเห็นว่า "ช่องว่าง" ระหว่างจุดต่าง ๆ เป็นM-BM- ตัวอักษรพิเศษ... ไม่แน่ใจว่าพวกมันพุ่งเข้ามาที่นั่นได้อย่างไร แต่พวกเขาต้องการการแทนที่ หากคุณไม่สามารถกำหนดเป้าหมายได้ดีผลงานนี้: sed -r 's/(\s\..\..\.)/ dot dot dot/ig' sed-dots
Oli

@Oli มันใช้งานได้ ขอบคุณมาก! คุณช่วยอธิบายไวยากรณ์ได้ไหม คุณแน่ใจหรือว่ามันไม่มีผลข้างเคียงใด ๆ และจะไม่แทนที่สิ่งอื่นใด? เท่าที่ฉันเห็น RegExp นี้จะจับคู่อักขระใด ๆ หลังจุด อย่างไรก็ตาม M-BM ไม่ใช่ตัวละครตัวหนึ่งมันเป็นสามตัว ดังนั้นมันจะทำงานได้อย่างไร
Rafal


0

ฉันสามารถใช้ไฟล์ของคุณเมื่อฉันวิ่งผ่าน:

tr '\240' ' ' < sed-dots.txt > sed-dots.new

สิ่งนี้ใช้ได้โดยไม่มีขั้นตอนการแปลง:

sed 's/[[:blank:]]\.[[:blank:]]\.[[:blank:]]\./.../g' sed-dots.txt

มันไม่ทำงาน. ฉันเดาว่าเหตุผลคือตัวละคร M-BM แปลก ๆ ที่ @Oli พบ
Rafal
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.