2017-02-24 285 views
1

我遇到以下問題。sed查找並替換爲僅發生特定次數

我有一個序列文件,我想找到一個特定的模式,並用另一個模式替換,但只有特定的次數。

如:

ABCDEFGHIJKLMN 
ABCDEFGHIJKLMN 
ABCDEFGHIJKLMN 
ABCDEFGHIJKLMN 
ABCDEFGHIJKLMN 
ABCDEFGHIJKLMN 

我想找到 「DEFGHI」,並以 「ABCDEF」 取代它只有3次。

sed -i 's/DEFGHI/ABCDEF/g' /home/user/test.txt 

我不想全局替換;相反,我想只更換3次。

+0

你爲什麼想用自身替換'DEFGHI'?顯示你想要的輸出。 – toolic

+0

對不起。我想用另一個模式替換。例如:使用ABCDEF的DEFGHI – manoj

+0

這是非平凡的。每行可能出現多於一次的模式? – melpomene

回答

0

您可以替換第一次出現的發現三次:

sed -i '0,/DEFGHI/s//ABCDEF/;0,/DEFGHI/s//ABCDEF/;0,/DEFGHI/s//ABCDEF/' file 

輸出:

ABCABCDEFJKLMN 
ABCABCDEFJKLMN 
ABCABCDEFJKLMN 
ABCDEFGHIJKLMN 
ABCDEFGHIJKLMN 
ABCDEFGHIJKLMN 
2

這取代了給定模式的三倍,他們分佈在線條無論怎樣

perl -0777 -pe'$i += s/DEF/xxx/ while $i < 3' <data.txt> out.txt 

它假定圖案不會在線上被打破。它會傳遞字符串,每次從頭開始搜索。這與下面解釋的一個警告有關,並且不夠高效,但它很簡單。

如果替換件本身在與周圍文本組合時重新創建了該模式,則在下一次傳遞時也將替換它。這樣的替換必須包含模式本身的一部分,並以特定的方式。不過,如果這是一個問題,請告訴我。

問題中未指定處理可能的重疊模式。如果有任何解決方案將在下一個階段取代第一個解決方案,那麼重疊的解決方案將不復存在。

+0

評論者@melpomene提供幫助,謝謝 – zdim

+0

@sidyll的(刪除)答案有正確的想法,並有幫助,謝謝 – zdim

+0

謝謝。它按預期工作..非常感謝 – manoj

2

這可以使用bash完成,並且GNU sed的是這樣的:

sed -z -i "$(echo s/DEFGHI/ABCDEF/{3..1}\;)" yourfile 
  • {3..1}導致的s部分重複三次時間標誌3比1的每s命令只替換第三,第二次和第一次發生。倒序是必要的,以便計數和替換不會混淆。
  • -z採取所有的輸入行一次,因此計數是不是每行,但每個文件。

供您參考,這裏是圍繞回聲命令替換產生:

echo s/DEFGHI/ABCDEF/{3..1}\; 
> s/DEFGHI/ABCDEF/3; s/DEFGHI/ABCDEF/2; s/DEFGHI/ABCDEF/1; 
+1

@SLePort你是對的。我顛倒了序列。謝謝。 –

+0

對於sed + shell組合,它適用於除3以外的任意值。但是,這種「大括號擴展」,要清楚... bash?所以它是GNU sed + bash和bashlike shell。 – stevesliva