Sed

如何使用 sed 替換多行字元串?

  • March 31, 2022

我注意到,如果我添加\n到替換 using 的模式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

我怎樣才能讓它工作?

在最簡單的sed呼叫中,它在模式空間中有一行文本,即。輸入中的 1 行\n分隔文本。模式空間中的單行沒有\n……這就是為什麼你的正則表達式沒有找到任何東西。

您可以將多行讀入模式空間並以驚人的方式操作事物,但付出的努力超出了正常範圍。Sed 有一組命令允許這種類型的事情…這裡是sed 的命令摘要的連結. 這是我找到的最好的,讓我滾動。

但是,一旦您開始使用 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                   

引用自:https://unix.stackexchange.com/questions/26284