Sed: แทนที่รูปแบบในการขึ้นบรรทัดใหม่ทุกวินาทีหรือไม่


10

มีวิธีบอกsedให้เปลี่ยนลวดลายในทุก ๆ วินาทีหรือไม่? หรืออย่างน้อยในทุก ๆ วินาที? (แน่นอนว่าเป็นไปได้ด้วยสคริปต์ แต่ฉันถามตัวเองว่าsedสามารถทำได้หรือไม่)

แก้ไข

ฉันพบ

sed -e "s/pattern/replacement/g;n"

แต่มันถูกแทนที่ทุกครั้งที่เกิดขึ้นไม่ใช่ครั้งที่สอง

ตัวอย่าง

ไฟล์อินพุต:

I have a pattern in each line
Also the second line has the pattern
Another pattern here
And -- you guess it -- a pattern

ผลลัพธ์ที่ต้องการ:

I have a pattern in each line
Also the second line has the replacement
Another pattern here
And -- you guess it -- a replacement

คำตอบ:


6

ดู/programming/5858200/sed-replace-every-nth-occurrence

วิธีการแก้ปัญหาใช้ awk มากกว่า sed แต่ "ใช้เครื่องมือที่เหมาะสมสำหรับงาน" อาจหรือไม่เป็นไปได้ที่จะทำใน sed แต่แม้ว่าจะเป็นมันจะง่ายขึ้นมากในเครื่องมือเช่น awk หรือ perl


1
ใช้สิ่งที่ฉันได้เรียนรู้ที่นั่นฉันทำความสะอาดsed -e 'n;s/2004-2009/6e législature/g'ซึ่งแก้ไขปัญหาของฉันได้
Matthieu Riegler

1
ว่าจะไม่ได้รับทุกวินาทีที่เกิดขึ้นก็จะค้นหารูปแบบของคุณในทุกวินาทีบรรทัด เช่นข้ามบรรทัดที่ 1, 3, 5, 7, ฯลฯ แน่นอนว่าอาจยังใช้งานได้กับเอกสารเฉพาะของคุณ
cas

ฉันรู้แล้ว นั่นคือสิ่งที่ฉันต้องการจริง
Matthieu Riegler

14
sed 's/pattern/replacement/2'

จะแทนที่การเกิดขึ้นครั้งที่สองในทุกบรรทัดที่มีรูปแบบ


ถ้าคุณมี GNU sed:

sed '1~2N ; s/pattern/replacement/2'

เริ่มต้นจากบรรทัดที่หนึ่ง1บรรทัดหลังจากนั้นจะถูกเพิ่มลงในพื้นที่รูปแบบNจากนั้นsคำสั่งจะแทนที่การเกิดขึ้นครั้งที่สองของรูปแบบ จากนั้นsedจะเลื่อนสองบรรทัดลง~2และทำซ้ำ


ฉันไม่ต้องการวินาที แต่ทุกวินาที
Matthieu Riegler

ฉันมีหนึ่งรูปแบบต่อบรรทัด นั่นไม่ได้ผล
Matthieu Riegler

คงจะดีที่ได้รู้ว่าก่อนหน้านี้ ดังนั้นรูปแบบเกิดขึ้นในบรรทัดที่หนึ่งสองสามและสี่ (ฯลฯ ) และคุณต้องการแทนที่รูปแบบในบรรทัดที่สองสี่และอื่น ๆ ?
llua

ทางเลือกที่สั้นกว่าอาจเป็นได้code(sed '1 ~ 2s / รูปแบบ / การเปลี่ยน /')
jaap

2

การตีความง่าย ๆ :

ในบรรทัดแรกที่มี PATTERN เกิดขึ้นอย่างน้อยหนึ่งครั้งคุณต้องการละเว้นและพิมพ์บรรทัดตามที่เป็น บนบรรทัดที่สองที่มีการเกิดขึ้นอย่างน้อยหนึ่งครั้งคุณต้องการแทนที่อินสแตนซ์แรกของ PATTERN ด้วย REPLACEMENT ในบรรทัดที่สามที่มี PATTERN เกิดขึ้นอย่างน้อยหนึ่งครั้งคุณต้องการพิมพ์บรรทัดตามที่เป็น ในบรรทัดที่สี่ที่มีการเกิดขึ้นอย่างน้อยหนึ่งครั้งคุณต้องการแทนที่อินสแตนซ์แรกของ PATTERN ด้วย REPLACEMENT และอื่น ๆ เส้นที่ไม่ตรงกับรูปแบบควรพิมพ์โดยไม่มีการเปลี่ยนแปลง

ซึ่งสามารถทำได้อย่างง่ายดายด้วย Sed เช่น:

sed -e '/PATTERN/ { :inside' -e 'n;s//REPLACEMENT/;t' -e 'b inside' -e '}'

หรือด้วยช่องว่างที่น้อยลงและฉลากที่สั้นกว่า:

sed -e '/PATTERN/{:i' -e 'n;s//REPLACEMENT/;t' -e 'b i' -e '}'

แก้ไข: ฉันเพิ่งอ่านคำถามอีกครั้งและพบการตีความที่ยากขึ้น:

แทนที่การเกิดแบบที่สองของ PATTERN ในเอกสารทั้งหมดด้วย REPLACEMENT ไม่ว่าจะเกิดขึ้นในบรรทัดเดียวกันกับการเกิดครั้งแรกหรือไม่ ปล่อยให้เหตุการณ์ที่หนึ่งและที่สามไม่เปลี่ยนแปลง เป็นต้น

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


แทนที่test ของคุณด้วยquit และนำเข้าเช่น{ sed '...'; cat; } <inputสำหรับการเปลี่ยนเพียงครั้งเดียว
mikeserv

1

คุณสนิทมากเพียงข้ามบรรทัดแรก:

sed '1n;s/pattern/replacement/;n'

เหตุใดจึงควรawkเป็นเครื่องมือที่ดีกว่าในกรณีนี้


0

หนึ่งรูปแบบสัญลักษณ์ภายในหนึ่งบรรทัด: sed 's / (a ​​[^ a] *) a / \ 1c / g'

ทุกรูปแบบที่สอง (อาจมีรูปแบบการจับคู่รูปแบบเดียวต่อบรรทัดเท่านั้นหากปรากฏอย่างน้อยสองรายการต่อหนึ่งบรรทัดจะปรากฏเฉพาะรูปแบบที่สองเท่านั้น)

echo -e "test\nreplace_me\ntest\ntest\nreplace_me\nreplace_me\nreplace_me" | \
sed '/replace_me/{:a;N;/replace_me.*replace_me/!Ta;s/replace_me/replaced/2;}'
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.