ฉันจะลบข้อความทั้งหมดระหว่างวงเล็บปีกกาในไฟล์ข้อความหลายบรรทัดได้อย่างไร


10

ตัวอย่าง:

This is {
the multiline
text file }
that wants
{ to be
changed
} anyway.

ควรเป็น:

This is 
that wants
 anyway.

ฉันพบเธรดที่คล้ายกัน ในฟอรัม แต่ดูเหมือนว่าจะไม่สามารถใช้กับวงเล็บปีกกาแบบหลายบรรทัดได้

ถ้าเป็นไปได้ฉันต้องการวิธีการหนึ่งบรรทัดเช่นโซลูชันที่ใช้ grep, sed, awk ... เป็นต้น

แก้ไข: โซลูชั่นดูเหมือนจะตกลง แต่ฉันได้สังเกตเห็นว่าไฟล์ต้นฉบับของฉันรวมถึงการทำเครื่องหมายวงเล็บปีกกา ดังนั้นฉันกำลังเปิดคำถามใหม่ ขอบคุณทุกคน: ฉันจะลบข้อความทั้งหมดระหว่างวงเล็บปีกกาแบบซ้อนในไฟล์ข้อความแบบหลายบรรทัดได้อย่างไร?


1
ลองสิ่งนี้sed '/{/{:1;N;s/{.*}//;T1}' multiline.file
Costas

คำตอบ:


10
$ sed ':again;$!N;$!b again; s/{[^}]*}//g' file
This is 
that wants
 anyway.

คำอธิบาย:

  • :again;$!N;$!b again;

    นี่จะอ่านไฟล์ทั้งหมดในพื้นที่รูปแบบ

    :againเป็นฉลาก Nอ่านในบรรทัดถัดไป $!b againสาขากลับไปที่againป้ายกำกับโดยมีเงื่อนไขว่านี่ไม่ใช่บรรทัดสุดท้าย

  • s/{[^}]*}//g

    สิ่งนี้จะลบนิพจน์ทั้งหมดในวงเล็บปีกกา

บน Mac OSX ลอง:

sed -e ':again' -e N -e '$!b again' -e 's/{[^}]*}//g' file

การจัดฟันแบบซ้อน

ลองทำสิ่งนี้เป็นไฟล์ทดสอบที่มีเครื่องหมายวงเล็บซ้อนกันมากมาย:

a{b{c}d}e
1{2
}3{
}
5

นี่คือการแก้ไขเพื่อจัดการกับเครื่องหมายวงเล็บซ้อนกัน:

$ sed ':again;$!N;$!b again; :b; s/{[^{}]*}//g; t b' file2
ae
13
5

คำอธิบาย:

  • :again;$!N;$!b again

    นี่คือเหมือนก่อน: มันอ่านในไฟล์ทั้งหมด

  • :b

    bนี้กำหนดฉลาก

  • s/{[^{}]*}//g

    สิ่งนี้จะลบข้อความด้วยเครื่องหมายปีกกาตราบใดที่ข้อความนั้นไม่มีเครื่องหมายปีกกาอยู่ภายใน

  • t b

    bหากคำสั่งแทนดังกล่าวข้างต้นส่งผลให้เกิดการเปลี่ยนแปลงกระโดดกลับไปที่ป้าย ด้วยวิธีนี้คำสั่งทดแทนจะทำซ้ำจนกว่ากลุ่มวงเล็บปีกกาทั้งหมดจะถูกลบออก


คำตอบของคุณน่าจะสมบูรณ์แบบ ตราบใดที่คำถามใหม่ที่ฉันเพิ่งเปิด (อ่านคำถามเดิมEDIT) ไม่เหมือนกันฉันคิดว่าคุณควรตอบด้วย มันจะตกลงกับกฎของฟอรั่ม?
Sopalajo de Arrierez

@ John1024 คุณสามารถย้ายการแก้ไขของคุณได้ที่นี่เนื่องจาก OP ได้โพสต์คำถามใหม่เกี่ยวกับคำถามเดียวกัน
Ramesh

1
ตกลง. ฉันได้คัดลอกไปที่นั่นและแก้ไขเพื่อใช้ข้อความตัวอย่างในคำถามใหม่
John1024

5

Perl:

perl -0777 -pe 's/{.*?}//sg' file

หากคุณต้องการแก้ไขในสถานที่

perl -0777 -i -pe 's/{.*?}//sg' file

ที่อ่านไฟล์เป็นสตริงเดี่ยวและทำการค้นหาและแทนที่แบบโกลบอล

สิ่งนี้จะจัดการกับค้ำยันซ้อนกัน:

perl -ne 'do {$b++ if $_ eq "{"; print if $b==0; $b-- if $_ eq "}"} for split //'

ขอบคุณนี่มีประโยชน์มาก! นี้ช่วยให้ฉันแก้ปัญหาด้วยการสร้างสคริปต์เพื่อแทนที่เนื้อหาของฟังก์ชั่นภายในไม่กี่นาที VS ดิ้นรนกับ sed กับ ah..em เวลามากขึ้นแล้วฉันจะยอมรับ (hours..cough..cough)
AndrewD

4

sed:

sed '/{/{:1;N;s/{.*}//;T1}' multiline.file

เริ่มตั้งแต่บรรทัดด้วย{และรับบรรทัดถัดไป ( N) จนกระทั่ง{}สามารถทำการทดแทน ( ) ได้ ( Tหมายถึงกลับไปที่การทำเครื่องหมายโดย:หากไม่ทำการแทนที่)

การปรับเปลี่ยนเล็กน้อยจะเป็นจริงถ้ามีหลาย curle bracked ในหนึ่งบรรทัด

sed ':1; s/{[^}]*}// ; /{/ { /}/!N ; b1 }' multiline.file

นำสัญลักษณ์ทั้งหมดในวงเล็บ ( [^}]เท่ากับทุก exept สัญลักษณ์right bracketที่จะทำให้sedไม่โลภ) และถ้าในสายยังคงอยู่left bracked- right bracketกลับไปเริ่มต้นด้วยบรรทัดถัดไปเพิ่มถ้ามีไม่ได้

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