Text-Processing

第 n 個模式匹配的就地文件替換

  • October 30, 2019

我有一個包含很多行的文件,但我可以總結我的要求,如下所示:

           <DT><A HREF="http://127.0.0.1:1234/ABCDE/wp-admin/index.cfm?event&msg=secure&fr=sp">Wonderland(Site 3)</A>
           <DT><A HREF="http://127.0.0.1:5678/FGHIJ/wp-admin/index.cfm?event&msg=secure&fr=sp">abc (test)</A>
--
           <DT><A HREF="http://127.0.0.1:1234/ABCDE/wp-admin/index.cfm?event&msg=secure&fr=sp">Wonderland(Site 3)</A>
           <DT><A HREF="http://127.0.0.1:8303/CFIDE/administrator/index.cfm?event&msg=secure&fr=sp">xyz (Prod)</A>
--
           <DT><A HREF="http://127.0.0.1:1234/ABCDE/wp-admin/index.cfm?event&msg=secure&fr=sp">Wonderland(Site 3)</A>
           <DT><A HREF="http://127.0.0.1:8303/CFIDE/administrator/index.cfm?event&msg=secure&fr=sp">lmn (Prod)</A>

我必須在第一次出現後插入一個新行:

<DT><A HREF="http://127.0.0.1:1234/ABCDE/wp-admin/index.cfm?event&msg=secure&fr=sp">Wonderland(Site 3)</A>

類似於它,例如

<DT><A HREF="http://127.0.0.1:2323/xnmp/wp-admin/index.cfm?event&msg=secure&fr=sp">NewSite(Site 4)</A>

在第二次出現後插入一個新行,與上麵類似的另一個變數行,第三行匹配後也是如此。

我用各種組合嘗試過這樣的事情,但它不起作用:

input1='<DT><A HREF="http://127.0.0.1:1234/ABCDE/wp-admin/index.cfm?event&msg=secure&fr=sp">Wonderland(Site 3)</A>
output1='<DT><A HREF="http://127.0.0.1:2323/xnmp/wp-admin/index.cfm?event&msg=secure&fr=sp">NewSite(Site 4)</A>'
output2='<DT><A HREF="http://127.0.0.1:2324/xnmp/wp-admin/index.cfm?event&msg=secure&fr=sp">NewSite(Site 4)</A>'
output3='<DT><A HREF="http://127.0.0.1:2124/xnmp/wp-admin/index.cfm?event&msg=secure&fr=sp">NewSite(Site 4)</A>'
gawk -i inplace -v in2="$input1" -v voutput1="$output1" '/in2/{c++;if(c==1){sub(in2,in2 "\n" voutput3);c=0}}1' a  ; where a is my file name

我可以使用 sed 替換所有內容,但不能單獨替換。替代所有的工作:

sed -i.bak "s#$input1#$input1\n\t\t$output1#" a

預期輸出:

           <DT><A HREF="http://127.0.0.1:1234/ABCDE/wp-admin/index.cfm?event&msg=secure&fr=sp">Wonderland(Site 3)</A>
           <DT><A HREF="http://127.0.0.1:2323/xnmp/wp-admin/index.cfm?event&msg=secure&fr=sp">NewSite(Site 4)</A>
           <DT><A HREF="http://127.0.0.1:5678/FGHIJ/wp-admin/index.cfm?event&msg=secure&fr=sp">abc (test)</A>
--
           <DT><A HREF="http://127.0.0.1:1234/ABCDE/wp-admin/index.cfm?event&msg=secure&fr=sp">Wonderland(Site 3)</A>
           <DT><A HREF="http://127.0.0.1:2324/xnmp/wp-admin/index.cfm?event&msg=secure&fr=sp">NewSite(Site 4)</A>
           <DT><A HREF="http://127.0.0.1:8303/CFIDE/administrator/index.cfm?event&msg=secure&fr=sp">xyz (Prod)</A>
--
           <DT><A HREF="http://127.0.0.1:1234/ABCDE/wp-admin/index.cfm?event&msg=secure&fr=sp">Wonderland(Site 3)</A>
           <DT><A HREF="http://127.0.0.1:2124/xnmp/wp-admin/index.cfm?event&msg=secure&fr=sp">NewSite(Site 4)</A>
           <DT><A HREF="http://127.0.0.1:8303/CFIDE/administrator/index.cfm?event&msg=secure&fr=sp">lmn (Prod)</A>

不要儲存在變數中,而是將所有輸出(每行一個)放在文件中,說 outf 然後執行以下操作:

$ sed -e "\\#${input1}#R outf" a

這假設您使用的是 GNU sed。對更改感到滿意後,請引入 -i 選項。

解釋:

° Alternate delimiter needs to escaped by a backslash. In our case, # is the delimiter, so we escape it with a backslash.
° Wait a minute but I see two of them here, you'll be asking. Well coz, before what we write on the command line gets to sed is seen n processed by the shell. So since backslash is special within double quotes, we need to double it so that after shell has seen it, it shall be presented as one to sed. So the Universe is happy.
° Now comes the R command. This is a nonstandard command given by Gnu folks,  and is precisely what the doctor ordered for your scenario. It will print one line each time it is invoked and place that line after the current input line is printed.

********/菲尼。

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