Sed - แทนที่อักขระในบรรทัดที่ตรงกันใช่หรือไม่


21

ในไฟล์ที่มีบรรทัดเช่นนี้:

# lorem ipsum blah variable

ฉันต้องการลบ#อักขระ (ความคิดเห็น) ในบรรทัดเดียวกันที่มีสตริงที่เฉพาะเจาะจงแทน เป็นsedสิ่งที่ดีสำหรับเรื่องนี้?

ฉันกำลังดิ้นรนเพื่อให้การทำงานแบบมีเงื่อนไขนี้ ฉันมี "เงอะงะ" วิธีการทำเช่นนี้; ฉันสามารถค้นหาหมายเลขบรรทัดที่ตรงกันด้วยawkหรือsedจากนั้นใช้หมายเลขนี้ในsedคำสั่งแยกกันแต่ฉันเชื่อว่าสิ่งนี้สามารถทำได้ในวิธีที่ดีกว่ามาก

คำตอบ:


36

ใช้สตริงที่คุณกำลังมองหาเป็นตัวเลือกสำหรับบรรทัดที่จะดำเนินการเมื่อ:

sed '/ipsum/s/#//g'

/ipsum/เลือกบรรทัดที่มี "ipsum" และเฉพาะในบรรทัดเหล่านี้คำสั่งที่ตามมาจะถูกดำเนินการ คุณสามารถใช้เครื่องมือจัดฟันเพื่อรันคำสั่งเพิ่มเติม

/ipsum/{s/#//g;s/@/-at-/g;}

4
ฉันเห็นด้วย; นี่เป็นคำตอบที่ดีที่สุด (แม้ว่าไม่ใช่คำตอบเดียว) ความคิดเห็นที่: (1) 's/#//g'จะลบทุก#ตัวอักษรในบรรทัด หากนั่นไม่ใช่สิ่งที่คุณต้องการเอาออกg(ซึ่งหมายถึง "ทั่วโลก") (2) การแก้ไขไฟล์ในสถานที่ (ตามที่ถามในคำถาม) sed -iการใช้งาน
G-Man กล่าวว่า 'Reinstate Monica'

2
(3) เป็นเรื่องของสถานการณ์จริงของโลกถ้าคุณต้องการที่จะยกเลิกสายความคิดเห็นที่คุณอาจต้องการที่จะใช้sed -i '/ipsum/s/#[[:space:]]*//'เพื่อกำจัดช่องว่างใด ๆ #และแท็บทันทีดังต่อไปนี้ (4) คุณอาจต้องการพิจารณาการตรวจสอบว่า#อักขระตัวแรกไม่ใช่บรรทัดว่างในบรรทัด คำสั่งปัจจุบันจะลบจากบรรทัด# prompt "Enter # of ipsums:"
G-Man กล่าวว่า 'Reinstate Monica'

1
@ G-Man - นอกจากนี้ยอดเยี่ยม! ไปยัง pt ที่ 2 ของคุณ (พื้นที่ชั้นนำ) แล้วประมาณ: sed -i '/ipsum/s/^#[[:space:]]*//'?! ( ^หมายถึงจุดเริ่มต้นของบรรทัด$สำหรับจุดสิ้นสุดบรรทัด) - อย่างน้อยก็ใน gnu sed ...
Jeremy Davis

1
@ JeremyDavis: ใช่คุณสามารถยึด regex กับจุดเริ่มต้นของบรรทัดด้วย^แต่นั่นจะผิด ฉันมักจะแสดงความคิดเห็นออกรหัสเยื้องโดยใส่#ทันทีก่อนรหัสดังนั้น#เยื้อง ฉันสงสัยว่าฉันเป็นคนเดียวที่ทำอย่างนั้น
G-Man กล่าวว่า 'Reinstate Monica'

1
@ G-Man - ใช่แน่นอน! ขอบคุณฉันไม่ได้คิดอย่างนั้น ดังนั้นคุณยังต้องการที่จะตรวจสอบช่องว่างระหว่าง^และเพื่อให้บางสิ่งบางอย่างมากขึ้นเช่นนี้:# /ipsum/{/^[[:space:]]*#/s/#[[:space:]]*//}แม้ว่าถึงตอนนั้นขึ้นอยู่กับว่า#มันอยู่ที่ไหนมันก็ยังอาจทำให้เกิดปัญหา (เช่นในภาษาที่ใช้การเยื้อง / การแยกช่องว่าง)
Jeremy Davis

7
$ cat input.txt
# lorem ipsum blah variable
# lorem ipsum blat variable
# lorem ipsum blow variable
# lorem ipsum blip variable
# lorem ipsum blue variable

แล้ว:

$ sed 's|# \(.*blue.*\)|\1|' input.txt

ให้:

# lorem ipsum blah variable
# lorem ipsum blat variable
# lorem ipsum blow variable
# lorem ipsum blip variable
lorem ipsum blue variable

มันทำงานได้ดังต่อไปนี้:

The sบอกsedว่ามันควรจะแทนที่สิ่งที่แสดงออกปกติ

รูปแบบ# \(.*blue.*\)ที่แบ่งลงเป็น: ค้นหาแฮชแล้วตามด้วยเว้นวรรค Bracket ( \() เริ่มการจัดกลุ่ม .*blue.*เป็นคำที่blueมีอะไรก่อนและหลัง วงเล็บถัดไป ( \)) ปิดการจัดกลุ่ม

การแทนที่คือ\1การอ้างอิงกลับไปที่เนื้อหาของวงเล็บการจัดกลุ่มแรก


3

คุณสามารถใช้ Vim ในโหมด Ex:

ex -sc '/ipsum/s/#//|x' file
  1. s แทน

  2. x บันทึกและปิด


มันเท่ห์มาก ฉันไม่รู้เรื่องนั้น! TBH ฉันไม่แน่ใจว่ามันเป็นคำตอบที่ดีที่สุดสำหรับคำถามนี้ (IMO คำตอบที่ดีที่สุดคือคำตอบ) แต่ก็ยังเจ๋งมาก! ขอบคุณสำหรับการโพสต์
Jeremy Davis
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.