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


9

คำถามนี้มาจาก ฉันจะลบข้อความทั้งหมดระหว่างวงเล็บปีกกาในไฟล์ข้อความหลายบรรทัดได้อย่างไร (เหมือนกัน แต่ไม่มีข้อกำหนดสำหรับการซ้อน)

ตัวอย่าง:

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

ควรเป็น:

This is 
that wants
 anyway.

เป็นไปได้ไหมที่จะใช้คำสั่ง bash แบบบรรทัดเดียว (awk, sed, perl, grep, cut, tr ... ฯลฯ )

คำตอบ:


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

คำอธิบาย:

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

    สิ่งนี้อ่านได้ทั้งไฟล์

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

  • :b

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

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

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

  • t b

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


3

วิธีการ Perl:

$ perl -F"" -a00ne 'for (@F){$i++ if /{/; $i||print; $i-- if /}/}' file
This is 
that wants
 anyway

คำอธิบาย

  • -a: เปิดการแยกอัตโนมัติของตัวคั่นไฟล์ที่กำหนดโดย-Fใน@Fอาร์เรย์
  • -F"": ตั้งค่าตัวคั่นฟิลด์อินพุตให้ว่างซึ่งจะส่งผลให้แต่ละองค์ประกอบ@Fเป็นหนึ่งในอักขระอินพุต
  • -00: เปิด "โหมดย่อหน้า" โดยที่ "บรรทัด" ถูกกำหนดเป็นอักขระบรรทัดใหม่ต่อเนื่องสองตัว ซึ่งหมายความว่าไฟล์ทั้งหมดในกรณีนี้จะถือว่าเป็นบรรทัดเดียว หากไฟล์ของคุณมีหลายย่อหน้าและวงเล็บสามารถขยายได้หลายย่อหน้าให้ใช้-0777แทน
  • -ne: อ่านไฟล์อินพุตและใช้สคริปต์ที่กำหนดโดย-eแต่ละบรรทัด

ตัวสคริปต์เองนั้นค่อนข้างง่ายจริงๆ เคาน์เตอร์จะเพิ่มขึ้นโดยหนึ่งทุกครั้งที่{จะเห็นและ decremented }โดยหนึ่งสำหรับทุก ซึ่งหมายความว่าเมื่อตัวนับเป็น 0 เราไม่ได้อยู่ในวงเล็บและควรพิมพ์:

  • for (@F){}: ทำสิ่งนี้สำหรับแต่ละองค์ประกอบของ@Fตัวละครแต่ละตัวในบรรทัด
  • $i++ if /{/;: เพิ่มขึ้นทีละ$iตัวถ้าตัวละครนี้เป็น{
  • $i||print;: พิมพ์ยกเว้น$iตั้ง (0 นับเป็น unset)
  • $i-- if /}/: ลดลง$iหนึ่งถ้าตัวละครนี้เป็น}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.