พิมพ์บรรทัดระหว่าง (และไม่รวม) สองรูปแบบ


13

ฉันจะส่งแบบฟอร์มโดยใช้ cURL ซึ่งเนื้อหาบางส่วนมาจากไฟล์อื่นที่เลือกโดยใช้ sed

หากparam1เป็นรูปแบบการจับคู่บรรทัดจากไฟล์อื่น ๆ ที่ใช้sedคำสั่งด้านล่างจะทำงานได้ดี:

curl -d param1="$(sed -n '/matchpattern/p' file.txt)" -d param2=value2 http://example.com/submit

ตอนนี้ไปที่ปัญหา ฉันต้องการแสดงเฉพาะข้อความระหว่าง 2 รูปแบบการจับคู่ที่ไม่รวมรูปแบบการจับคู่นั้น

ช่วยบอกว่าfile.txtประกอบด้วย:

Bla bla bla
firstmatch
It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout.
secondmatch
The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters, as opposed to using 'Content here, content here', making it look like readable English.

ปัจจุบันจำนวนมาก "beetween 2 จับคู่รูปแบบ" sedคำสั่งจะไม่ลบและfirstmatchsecondmatch

ฉันต้องการผลลัพธ์ที่จะกลายเป็น:

It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout.

คำตอบ:


15

นี่เป็นวิธีหนึ่งที่คุณสามารถทำได้:

sed '1,/firstmatch/d;/secondmatch/,$d' 

อธิบาย: จากบรรทัดแรกไปยังบรรทัดที่ตรงกับfirstmatchลบ จากการจับคู่สายsecondmatchไปบรรทัดสุดท้ายลบ


6

ใน awk:

awk '
  $1 == "secondmatch" {print_me = 0}
  print_me {print}
  $1 == "firstmatch {print_me = 1}
'

ที่นี่เกี่ยวกับความเร็ว: unix.stackexchange.com/a/194662/16920
LéoLéopold Hertz 준영

แล้วความเร็วล่ะ?
เกล็นแจ็คแมน

ฉันคิดว่า SED ดีกว่า AWK ตรงเวลา
LéoLéopold Hertz

5

อีกsedวิธีการแก้ปัญหาจะล้มเหลวหากfirstmatchเกิดขึ้นบน 1 เส้น1

ทำให้มันง่ายใช้ช่วงเดียวและ2 regex ที่ว่างเปล่า:
พิมพ์ทุกอย่างในช่วงนั้นไม่รวมช่วงสิ้นสุด (ปิดการพิมพ์อัตโนมัติ) 3 :

sed -n '/firstmatch/,/secondmatch/{//!p;}' infile

หรือสั้นกว่าลบทุกอย่างที่ไม่อยู่ในช่วงนั้นและลบช่วงสิ้นสุดด้วย:

sed '/firstmatch/,/secondmatch/!d;//d' infile


1: เหตุผลที่ถูกว่า ถ้าอยู่ที่สองคือ regexp แล้วการตรวจสอบสำหรับการแข่งขันสิ้นสุดจะเริ่มต้นด้วยบรรทัดต่อไปนี้สายซึ่งตรงกับที่อยู่แรก
ดังนั้น/firstmatch/จะไม่ถูกประเมินสำหรับบรรทัดที่ 1 ของอินพุตsedเพียงแค่ลบมันตามที่ตรงกับหมายเลขบรรทัดใน1,/RE/และไปยังบรรทัดที่ 2 ซึ่งตรวจสอบว่าบรรทัดนั้นตรงกันหรือไม่/firstpattern/

2: เมื่อREGEXว่างเปล่า (เช่น//) sedจะทำงานราวกับว่ามีการใช้REGEXล่าสุดในคำสั่งสุดท้าย (ไม่ว่าจะเป็นที่อยู่หรือเป็นส่วนหนึ่งของคำสั่งทดแทน)

3: ;}ไวยากรณ์สำหรับsedการใช้งานที่ทันสมัย กับคนที่มีอายุมากกว่าใช้ขึ้นบรรทัดใหม่แทนเซมิโคลอนหรือนิพจน์แยกกันเช่นsed -n -e '/firstmatch/,/secondmatch/{//!p' -e '}' infile


คุณช่วยอธิบายสิ่งที่//ทำอยู่ข้างในได้{…}ไหม?
G-Man กล่าวว่า 'Reinstate Monica'

ขอบคุณ แต่คุณตกหลุมพรางของฉัน ฉันรู้ว่านั่น//หมายถึงการแสดงออกปกติครั้งสุดท้ายที่ใช้; /secondmatch/จากทุกอย่างที่ผมเคยอ่านที่ควรจะเป็น ฉันได้ตรวจสอบผ่านการทดสอบว่าคำสั่งของคุณใช้งานได้และฉันได้ข้อสรุปว่ามันทำงานเป็น/firstmatch|secondmatch/(ซึ่งคุณได้ยืนยันแล้ว) แต่ฉันไม่สามารถหาเอกสารใด ๆ ได้ (ไม่ใช่แม้แต่POSIX เอกสารที่คุณเชื่อมโยงหรือGNU sed คู่มือ ) ที่อธิบายพฤติกรรมนี้ … (ต่อ)
G-Man กล่าวว่า 'Reinstate Monica'

(ต่อ) ... รับรองการทดลอง: (I) ในsed(1) ถ้าผมทำ/first/,4แล้วทำหน้าที่เหมือน// /first/(2) ถ้าฉันทำ2,/second/แล้ว//ได้รับข้อผิดพลาด“ ไม่นิพจน์ปกติก่อนหน้า” (ฉันพบว่านี่เป็นความล้มเหลวที่เห็นได้ชัดเพื่อติดตามพฤติกรรมที่ระบุ) (3) การเพิ่ม--posixไม่ได้เปลี่ยนแปลงอย่างใดอย่างหนึ่งข้างต้น (II) ในโปรแกรมอื่น: (4) ในvi, หลังจากนั้น/first/,/second/, //ทำหน้าที่เหมือน/second/(และรูปแบบอื่น ๆ นอกจากนี้ยังมีการใช้งานที่มีเหตุผลของกฎเอกสาร) … (ต่อ)
G-Man กล่าวว่า 'Reinstate Monica'

(ต่อ) … (5)  awkดูเหมือนจะไม่มีความคิดในเรื่อง“ การใช้ RE ครั้งล่าสุด”; //อ้างถึงที่ไม่ใช่ตัวละครก่อนหรือหลังตัวละครใด ๆ (ฉันขอเชิญคุณลองecho -- | awk '{ gsub(//, "cha"); print }')
G-Man พูดว่า 'Reinstate Monica'

ดังนั้นคุณอ่าน“ทั่วไป REGEX สุดท้ายที่ใช้ในคำสั่งสุดท้าย” เป็น“ทั่วไป REGEX สุดท้าย (s) ที่ใช้ในคำสั่งสุดท้าย” และเพื่อให้คุณ (ถูกต้อง) /first|second/เดาว่ามันหมายถึง โชคดีนะคุณ. ฉันพูดถึงโปรแกรมอื่น ๆ เพื่อแสดงให้เห็นว่านี่ไม่ใช่การประชุม regex ทั่วทั้งระบบ ใครก็ตามที่เพิ่มมันลงไปsedไม่ต้องกังวลที่จะเพิ่มเข้าไปvimซึ่งมันจะทำให้รู้สึกถึง :-) ⁠
G-Man กล่าวว่า 'Reinstate Monica'
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.