ฉันจะใช้ sed เพื่อแทนที่สตริงหลายบรรทัดได้อย่างไร


243

ฉันสังเกตเห็นว่าถ้าฉันเพิ่ม\nรูปแบบสำหรับการทดแทนโดยใช้sedมันไม่ตรงกัน ตัวอย่าง:

$ cat > alpha.txt
This is
a test
Please do not
be alarmed

$ sed -i'.original' 's/a test\nPlease do not/not a test\nBe/' alpha.txt

$ diff alpha.txt{,.original}

$ # No differences printed out

ฉันจะทำให้เรื่องนี้ทำงานได้อย่างไร


วิธีแก้ปัญหาสมาร์ทที่นี่: unix.stackexchange.com/a/445666/61742 แน่นอนมันไม่เกี่ยวกับการแสดง! ตัวเลือกที่ดีอื่น ๆ สำหรับการแทนที่อาจเป็น awk, perl และ python มีคนอื่นอีกหลายคน แต่ฉันเชื่อว่า awk นั้นเป็นสากลที่สุดในลีนุกซ์รุ่นต่างๆ (ตัวอย่าง) ขอบคุณ!
Eduardo Lucio

คำตอบ:


235

ในการเรียกsed ที่ง่ายที่สุดจะมีข้อความหนึ่งบรรทัดในพื้นที่รูปแบบเช่น \nข้อความที่คั่นด้วย1 บรรทัดจากอินพุต บรรทัดเดียวในพื้นที่รูปแบบนั้นไม่มี\n... นั่นคือเหตุผลที่ regex ของคุณไม่พบอะไรเลย

คุณสามารถอ่านหลายบรรทัดใน pattern-space และจัดการกับสิ่งต่าง ๆ ได้อย่างน่าประหลาดใจ แต่ด้วยความพยายามมากกว่าปกติ .. Sed มีชุดคำสั่งที่อนุญาตให้ใช้สิ่งนี้ ... นี่คือลิงค์ไปยังCommand Summary สำหรับ sed . มันเป็นสิ่งที่ดีที่สุดที่ฉันได้พบและทำให้ฉันหมุน

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

เรื่องย่อ: ใช้สิ่งที่เรียบง่ายและอาจจะมากกว่า แต่โดยทั่วไปเมื่อมันเกินกว่าจะทำงานกับบรรทัดเดียวคนส่วนใหญ่ชอบสิ่งอื่น ...
ฉันจะให้คนอื่นแนะนำอย่างอื่น .. ฉัน จริง ๆ ไม่แน่ใจว่าตัวเลือกที่ดีที่สุดคืออะไร (ฉันใช้ sed แต่นั่นเป็นเพราะฉันไม่รู้จัก perl ดีพอ)


sed '/^a test$/{
       $!{ N        # append the next line when not on the last line
         s/^a test\nPlease do not$/not a test\nBe/
                    # now test for a successful substitution, otherwise
                    #+  unpaired "a test" lines would be mis-handled
         t sub-yes  # branch_on_substitute (goto label :sub-yes)
         :sub-not   # a label (not essential; here to self document)
                    # if no substituion, print only the first line
         P          # pattern_first_line_print
         D          # pattern_ltrunc(line+nl)_top/cycle
         :sub-yes   # a label (the goto target of the 't' branch)
                    # fall through to final auto-pattern_print (2 lines)
       }    
     }' alpha.txt  

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

sed '/^a test$/{$!{N;s/^a test\nPlease do not$/not a test\nBe/;ty;P;D;:y}}' alpha.txt

นี่คือคำสั่งของฉัน "โกงแผ่น"

:  # label
=  # line_number
a  # append_text_to_stdout_after_flush
b  # branch_unconditional             
c  # range_change                     
d  # pattern_delete_top/cycle          
D  # pattern_ltrunc(line+nl)_top/cycle 
g  # pattern=hold                      
G  # pattern+=nl+hold                  
h  # hold=pattern                      
H  # hold+=nl+pattern                  
i  # insert_text_to_stdout_now         
l  # pattern_list                       
n  # pattern_flush=nextline_continue   
N  # pattern+=nl+nextline              
p  # pattern_print                     
P  # pattern_first_line_print          
q  # flush_quit                        
r  # append_file_to_stdout_after_flush 
s  # substitute                                          
t  # branch_on_substitute              
w  # append_pattern_to_file_now         
x  # swap_pattern_and_hold             
y  # transform_chars                   

167
ยิงฉันตอนนี้ ไวยากรณ์แย่ที่สุดที่เคยมีมา!
Gili

53
นี่เป็นคำอธิบายที่น่าอัศจรรย์ แต่ฉันอยากเห็นด้วยกับ @Gili
gatoatigrado

11
แผ่นโกงของคุณมีทุกอย่าง
konsolebox

3
คุณไม่จำเป็นต้องใช้เลเบลเพื่อใช้tคำสั่งที่นี่ - เมื่อไม่ได้รับเลเบลมันจะมีค่าเริ่มต้นที่จะแตกแขนงไปจนถึงจุดสิ้นสุดของสคริปต์ ดังนั้นsed '/^a test$/{$!{N;s/^a test\nPlease do not$/not a test\nBe/;t;P;D}}' alpha.txtไม่ตรงเช่นเดียวกับคำสั่งของคุณในทุกสถานการณ์ แน่นอนสำหรับการนี้โดยเฉพาะอย่างยิ่งไฟล์sed '/test/{N;s/.*/not a test\nBe/}' alpha.txtจะเป็นสิ่งเดียวกันเช่นกัน แต่ตัวอย่างแรกของฉันคือเหตุผลที่เทียบเท่าสำหรับทุกไฟล์ที่เป็นไปได้ นอกจากนี้โปรดทราบว่า\nในสตริงการแทนที่จะไม่สร้างบรรทัดใหม่ คุณต้องมีแบ็กสแลช `` `ตามด้วยการขึ้นบรรทัดใหม่เพื่อทำเช่นนั้น
Wildcard

9
โปรดทราบว่าไวยากรณ์นั้นเป็นของ GNU โดยเฉพาะ ( #คำสั่งไม่ได้ถูกแยกออกจากก่อนหน้านี้\nใน RHS ของs) ด้วย GNU sedคุณยังสามารถใช้-zเพื่อใช้บันทึกที่คั่นด้วย NUL (และจากนั้น slurp ในอินพุตทั้งหมดถ้าเป็นข้อความ (ซึ่งโดยนิยามไม่ได้มี NULs))
Stéphane Chazelas

181

ใช้perlแทนsed:

$ perl -0777 -i.original -pe 's/a test\nPlease do not/not a test\nBe/igs' alpha.txt
$ diff alpha.txt{,.original}
2,3c2,3
< not a test
< Be
---
> a test
> Please do not

-pi -eเป็นลำดับบรรทัดคำสั่ง "แทนที่ในสถานที่" ของคุณและ -0777 ทำให้ Perl ไฟล์ slurp ทั้งหมด ดูperldoc perlrunเพื่อหาข้อมูลเพิ่มเติมเกี่ยวกับมัน


3
ขอบคุณ! สำหรับการทำงานหลายสาย, Perl ชนะมือ! ฉันลงเอยด้วยการใช้ `$ perl -pi -e 's / bar / baz /' fileA` เพื่อเปลี่ยนไฟล์แบบแทนที่
Nicholas Tolley Cottrell

3
เป็นเรื่องธรรมดามากที่ผู้โพสต์ดั้งเดิมจะถามsedและตอบกลับโดยใช้ awk หรือ perl ปรากฏ ฉันคิดว่ามันไม่ได้อยู่ในหัวข้อดังนั้นขอโทษ แต่ฉันยิงหนึ่งลบ
Rho Phi

68
+1 & ไม่เห็นด้วยกับ Roberto บ่อยครั้งที่คำถามใช้ถ้อยคำเฉพาะเพื่อความไม่รู้วิธีการที่ดีกว่า เมื่อไม่มีความแตกต่างเชิงบริบท (เช่นที่นี่) การแก้ปัญหาที่ดีที่สุดควรได้รับโปรไฟล์อย่างน้อยเท่ากับคำถามที่เฉพาะเจาะจง
geotheory

56
ฉันคิดว่าsedคำตอบข้างต้นพิสูจน์ให้เห็นว่าคำตอบ Perl อยู่ในหัวข้อ
reinierpost

7
ง่ายขึ้นเล็กน้อย: ด้วย "-p0e" ไม่จำเป็นต้องใช้ "-0777" unix.stackexchange.com/a/181215/197502
Weidenrinde

96

ฉันคิดว่าจะเป็นการดีกว่าที่จะแทนที่\nสัญลักษณ์ด้วยสัญลักษณ์อื่นแล้วทำงานตามปกติ:

เช่นรหัสที่มาไม่ทำงาน:

cat alpha.txt | sed -e 's/a test\nPlease do not/not a test\nBe/'

สามารถเปลี่ยนเป็น:

cat alpha.txt | tr '\n' '\r' | sed -e 's/a test\rPlease do not/not a test\rBe/'  | tr '\r' '\n'

หากใครไม่ทราบ\nก็คือการสิ้นสุดบรรทัด UNIX \r\n- windows, \r- classic Mac OS ข้อความ UNIX ปกติไม่ได้ใช้\rสัญลักษณ์ดังนั้นจึงปลอดภัยที่จะใช้สำหรับกรณีนี้

นอกจากนี้คุณยังสามารถใช้สัญลักษณ์แปลกใหม่เพื่อแทนที่ \ n ได้ชั่วคราว เป็นตัวอย่าง - \ f (สัญลักษณ์ฟีดฟอร์ม) คุณสามารถค้นหาสัญลักษณ์เพิ่มเติมที่นี่

cat alpha.txt | tr '\n' '\f' | sed -e 's/a test\fPlease do not/not a test\fBe/'  | tr '\f' '\n'

11
+1 สำหรับแฮ็คที่ฉลาดคนนี้! มีประโยชน์อย่างยิ่งคือคำแนะนำเกี่ยวกับการใช้สัญลักษณ์แปลกใหม่เพื่อแทนที่บรรทัดใหม่ชั่วคราวเว้นแต่คุณจะแน่ใจอย่างแน่นอนเกี่ยวกับเนื้อหาของไฟล์ที่คุณกำลังแก้ไข
L0j1k

นี้ไม่ได้ทำงานตามที่เขียนไว้ใน OS X ได้ แต่หนึ่งต้องเปลี่ยนทุกกรณี\rในการโต้เถียงไปด้วยsed $(printf '\r')
abeboparebop

@abeboparebop: พบที่ยอดเยี่ยม! 👍อีกวิธีหนึ่งคือติดตั้ง GNU โดยใช้ homebrew: stackoverflow.com/a/30005262
ssc

@abeboparebop บน OSX คุณเพียงแค่ต้องเพิ่ม$ก่อนสตริง sed เพื่อป้องกันไม่ให้มันจากการแปลงไปยัง\r rตัวอย่างสั้น ๆ : sed $'s/\r/~/'. ตัวอย่างเต็ม:cat alpha.txt | tr '\n' '\r' | sed $'s/a test\rPlease do not/not a test\rBe/' | tr '\r' '\n'
wisbucky

40

ทุกสิ่งที่พิจารณาว่าการกลืนทั้งไฟล์อาจเป็นวิธีที่เร็วที่สุด

ไวยากรณ์พื้นฐานมีดังนี้:

sed -e '1h;2,$H;$!d;g' -e 's/__YOUR_REGEX_GOES_HERE__...'

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

สำหรับสถานการณ์แฮ็คและสแลชอื่น ๆ ทั้งหมดเพียงแค่เตรียม-e '1h;2,$H;$!d;g'ตามด้วยsedอาร์กิวเมนต์ regex ดั้งเดิมของคุณ

เช่น

$ echo -e "Dog\nFox\nCat\nSnake\n" | sed -e '1h;2,$H;$!d;g' -re 's/([^\n]*)\n([^\n]*)\n/Quick \2\nLazy \1\n/g'
Quick Fox
Lazy Dog
Quick Snake
Lazy Cat

อะไร-e '1h;2,$H;$!d;g'ทำอย่างไร

1, 2,$, $!ส่วน specifiers บรรทัดที่ จำกัด ซึ่งบรรทัดคำสั่งโดยตรงวิ่งต่อไปนี้บน

  • 1: บรรทัดแรกเท่านั้น
  • 2,$: ทุกบรรทัดเริ่มจากวินาที
  • $!: ทุกบรรทัดนอกเหนือจากที่ผ่านมา

ขยายดังนั้นนี่คือสิ่งที่เกิดขึ้นในแต่ละบรรทัดของอินพุตบรรทัด N

  1: h, d
  2: H, d
  3: H, d
  .
  .
N-2: H, d
N-1: H, d
  N: H, g

gคำสั่งไม่ได้รับการระบุสาย แต่ก่อนdคำสั่งมีคำสั่งพิเศษ " เริ่มต้นรอบถัดไป. " และนี้จะป้องกันgจากการทำงานในสายทั้งหมดยกเว้นสุดท้าย

สำหรับความหมายของแต่ละคำสั่ง:

  • ครั้งแรกhตามด้วยHs ในแต่ละสำเนาบรรทัดกล่าวว่าสายของใส่ลงในsed's ถือพื้นที่ (คิดว่าบัฟเฟอร์ข้อความโดยพลการ)
  • หลังจากนั้นdทิ้งแต่ละบรรทัดเพื่อป้องกันไม่ให้บรรทัดเหล่านี้ถูกเขียนไปยังเอาต์พุต พื้นที่ถือแต่ถูกเก็บรักษาไว้
  • ในที่สุดในบรรทัดสุดท้ายgคืนค่าการสะสมของทุกบรรทัดจากพื้นที่พักเพื่อให้sedสามารถเรียกใช้ regex ในอินพุตทั้งหมด (แทนที่จะเป็นแบบ line-at-a-time) และด้วยเหตุนี้จึงสามารถ ตรงกับ\ns

38

sedมีสามคำสั่งในการจัดการการดำเนินงานหลายคู่สาย: N, DและP(เปรียบเทียบกับปกติ n , dและp)

ในกรณีนี้คุณสามารถจับคู่บรรทัดแรกของรูปแบบของคุณใช้Nเพื่อต่อท้ายบรรทัดที่สองกับพื้นที่ว่างของรูปแบบแล้วใช้sเพื่อทำการทดแทนของคุณ

สิ่งที่ต้องการ:

/a test$/{
  N
  s/a test\nPlease do not/not a test\nBe/
}

2
นี่มันเจ๋งมาก! ง่ายกว่าคำตอบที่ยอมรับและยังคงมีประสิทธิภาพ
jeyk

และทุกคนที่เกี่ยวข้องกับพื้นที่การระงับ ( G, H, x... ) สามารถเพิ่มบรรทัดเพิ่มเติมลงในพื้นที่รูปแบบด้วยsคำสั่งได้เช่นกัน
Stéphane Chazelas


วิธีการแก้ปัญหานี้ไม่ทำงานกับกรณีดังต่อไปนี้ "นี่คือ \ na ทดสอบ \ na ทดสอบ \ n กรุณาอย่า \ n ต้องตื่นตระหนก"
mug896

@ mug896 คุณอาจต้องการNคำสั่งหลายคำสั่ง
loa_in_

15

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

awk -v RS='a' '{gsub(/hello/, "world"); print}'

หากไม่มีการขึ้นบรรทัดใหม่ต่อเนื่องสองครั้งในสตริงการค้นหาของคุณคุณสามารถใช้ "ย่อหน้าโหมด" ของ awk (บรรทัดว่างหนึ่งบรรทัดหรือมากกว่านั้นแยกต่างหากบันทึก)

awk -v RS='' '{gsub(/hello/, "world"); print}'

ทางออกที่ง่ายคือการใช้ Perl และโหลดไฟล์ลงในหน่วยความจำอย่างเต็มที่

perl -0777 -pe 's/hello/world/g'

1
วิธีการใช้คำสั่ง perl กับไฟล์?
sebix

2
perl -0777 -pe '…' <input-file >output-file@sebix หากต้องการแก้ไขไฟล์ให้ถูกต้องperl -0777 -i -pe '…' filename
Gilles

3
ดูเพิ่มเติม GNU sed's -zตัวเลือก (เพิ่มในปี 2012 seq 10 | sed -z 's/4\n5/a\nb/'หลังจากคำตอบที่ถูกโพสต์)
Stéphane Chazelas

7

ฉันคิดว่านี่เป็นวิธีการแก้ปัญหาสำหรับการจับคู่ 2 บรรทัด

sed -n '$!N;s@a test\nPlease do not@not a test\nBe@;P;D' alpha.txt

ถ้าคุณต้องการจับคู่ 3 บรรทัดแล้ว ...

sed -n '1{$!N};$!N;s@aaa\nbbb\nccc@xxx\nyyy\nzzz@;P;D'

ถ้าคุณต้องการจับคู่ 4 บรรทัดแล้ว ...

sed -n '1{$!N;$!N};$!N;s@ ... @ ... @;P;D'

หากชิ้นส่วนทดแทนในคำสั่ง "s" ย่อขนาดบรรทัดแล้วซับซ้อนกว่าเล็กน้อยเช่นนี้

# aaa\nbbb\nccc shrink to one line "xxx"

sed -n '1{$!N};$!N;/aaa\nbbb\nccc/{s@@xxx@;$!N;$!N};P;D'

หากส่วน repacement ขยายเส้นก็ซับซ้อนกว่านี้เล็กน้อย

# aaa\nbbb\nccc grow to five lines vvv\nwww\nxxx\nyyy\nzzz

sed -n '1{$!N};$!N;/aaa\nbbb\nccc/{s@@vvv\nwww\nxxx\nyyy\nzzz@;P;s/.*\n//M;P;s/.*\n//M};P;D'

นี่น่าจะเป็นทางที่ดีที่สุด! ฉันเพิ่งใช้ "-i" แทน "-n" สำหรับการทดแทนสองบรรทัดเพราะนั่นคือสิ่งที่ฉันต้องการและโดยบังเอิญมันก็เป็นตัวอย่างของผู้ถามด้วย
Nagev

5
sed -i'.original' '/a test/,/Please do not/c not a test \nBe' alpha.txt

นี่/a test/,/Please do not/คือบล็อกข้อความ (หลายบรรทัด) cเป็นคำสั่งเปลี่ยนแปลงตามด้วยข้อความใหม่not a test \nBe

ในกรณีของข้อความที่จะถูกแทนที่มีความยาวมากฉันขอแนะนำไวยากรณ์อดีต


อุ๊ปส์ปัญหาคือ sed จะแทนที่ข้อความทั้งหมดในที่สุดระหว่าง / a ทดสอบ / และ / กรุณาอย่า / เช่นกัน ... :(
noonex

4
sed -e'$!N;s/^\(a test\n\)Please do not be$/not \1Be/;P;D' <in >out

เพียงแค่ขยายหน้าต่างของคุณในการป้อนข้อมูลเล็กน้อย

มันค่อนข้างง่าย นอกจากการทดแทนมาตรฐานแล้ว คุณต้องการเพียง$!N, PและDที่นี่


4

นอกเหนือจาก Perl แล้วแนวทางทั่วไปและมีประโยชน์สำหรับการแก้ไขแบบหลายบรรทัดสำหรับสตรีม (และไฟล์ด้วย) คือ:

ขั้นแรกให้สร้างตัวคั่นบรรทัดใหม่ที่ไม่ซ้ำกันตามที่คุณต้องการ

$ S=__ABC__                     # simple
$ S=__$RANDOM$RANDOM$RANDOM__   # better
$ S=$(openssl rand -hex 16)     # ultimate

จากนั้นในคำสั่ง sed ของคุณ (หรือเครื่องมืออื่น ๆ ) คุณแทนที่ \ n ด้วย $ {S} เช่น

$ cat file.txt | awk 1 ORS=$S |  sed -e "s/a test${S}Please do not/not a test\nBe/" | awk 1 RS=$S > file_new.txt

(awk แทนที่ตัวคั่นบรรทัด ASCII ด้วยของคุณและในทางกลับกัน)


2

นี่เป็นการแก้ไขคำตอบที่ฉลาดของ xara เล็กน้อยเพื่อให้ทำงานบน OS X (ฉันใช้ 10.10):

cat alpha.txt | tr '\n' '\r' | sed -e 's/a test$(printf '\r')Please do not/not a test$(printf '\r')Be/'  | tr '\r' '\n'

แทนการอย่างชัดเจนโดยใช้คุณต้องใช้\r$(printf '\r')


1
ในขณะที่printf '\r'(หรือecho -e '\r') ทำงานได้อย่างถูกต้องโปรดทราบว่าคุณสามารถใช้ไวยากรณ์ของเชลล์$'\r'เพื่ออ้างถึงตัวอักษรที่ใช้ Escape ยกตัวอย่างเช่นecho hi$'\n'thereจะสะท้อนขึ้นบรรทัดใหม่ระหว่างและhi thereในทำนองเดียวกันคุณสามารถห่อสตริงทั้งหมดเพื่อให้แต่ละทับขวา\ จะหลบหนีอักขระที่ตามมาของ:echo $'hi\nthere'
Dejay เคลย์ตัน

1

ฉันต้องการเพิ่ม HTML สองสามบรรทัดลงในไฟล์โดยใช้ sed (และสิ้นสุดที่นี่) โดยปกติฉันแค่ใช้ Perl แต่ฉันอยู่ในกล่องที่มีสติไม่ดีและไม่มาก ฉันพบว่าถ้าฉันเปลี่ยนสตริงเป็นบรรทัดเดียวและปล่อย bash / sed แก้ไข \ t \ n ทุกอย่างทำงานได้:

HTML_FILE='a.html' #contains an anchor in the form <a name="nchor" />
BASH_STRING_A='apples'
BASH_STRING_B='bananas'
INSERT="\t<li>$BASH_STRING_A<\/li>\n\t<li>$BASH_STRING_B<\/li>\n<a name=\"nchor\"\/>"
sed -i "s/<a name=\"nchor"\/>/$INSERT/" $HTML_FILE

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


1

GNU sedมี-zตัวเลือกที่อนุญาตให้ใช้ไวยากรณ์ที่ OP พยายามใช้ ( หน้าคน )

ตัวอย่าง:

$ cat alpha.txt
This is
a test
Please do not
be alarmed
$ sed -z 's/a test\nPlease do not\nbe/not a test\nBe/' -i alpha.txt
$ cat alpha.txt
This is
not a test
Be alarmed

ระวัง:ถ้าคุณใช้^และ$ตอนนี้พวกเขาตรงกับจุดเริ่มต้นและจุดสิ้นสุดของบรรทัดที่คั่นด้วยอักขระ NUL (ไม่\n) และเพื่อให้แน่ใจว่าการจับคู่ในทุก\nบรรทัด(- แยก) ของคุณถูกแทนที่อย่าลืมใช้gธงสำหรับการทดแทนทั่วโลก (เช่นs/.../.../g)


เครดิต: @ stéphane-chazelas ได้กล่าวถึง -z เป็นครั้งแรกในความคิดเห็นด้านบน


0

Sed หยุดการป้อนข้อมูลในบรรทัดใหม่ มันเก็บเพียงหนึ่งบรรทัดต่อลูป
ดังนั้นจึงไม่มีวิธีการจับคู่\n(ขึ้นบรรทัดใหม่) หากพื้นที่รูปแบบไม่มีอยู่

อย่างไรก็ตามมีวิธีคุณสามารถทำให้ sed เก็บสองบรรทัดต่อเนื่องในพื้นที่รูปแบบโดยใช้การวนซ้ำ:

sed 'N;l;P;D' alpha.txt

เพิ่มการประมวลผลใด ๆ ที่จำเป็นระหว่าง N และ P (แทนที่l)

ในกรณีนี้ (2 บรรทัด):

$ sed 'N;s/a test\nPlease do not/not a test\nBe/;P;D' alpha.txt
This is
not a test
Be
be alarmed

หรือสำหรับสามบรรทัด:

$ sed -n '1{$!N};$!N;s@a test\nPlease do not\nbe@not a test\nDo\nBe@;P;D' alpha.txt 
This is
not a test
Do
Be alarmed

นั่นคือสมมติว่ามีการแทนที่จำนวนบรรทัดเดียวกัน

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