2011-04-21 123 views
5

我想知道我怎麼能替換整個file.For例如搜索模式的第一次出現,第一替換文件中的字符串的使用sed的

import java.io.File; 
import java.io.File; 

被替換
import java.io.IOException; 
import java.io.File; 

我該如何使用sed來實現這個功能? 謝謝

+0

的可能重複(http://stackoverflow.com/questions/148451/how -to-使用-sed的更換的僅最第一現功能於一個文件) – 2011-04-21 11:32:39

回答

0

你可以使用一個shell腳本(bash)的

#!/bin/bash 

declare -i toggle=0 
while read -r line 
do 
     case "$line" in 
      *import*java.io.File*) 
      if [ $toggle -eq 1 ];then 
       echo "$line" 
       continue 
      fi 
      echo "import java.io.Exception"; 
      toggle=1 
      continue 
      ;; 
     esac 
     echo "$line" 
done < file 

樣本輸出

$> more file 
import java.util.Scanner; 
import java.io.File; 
import java.io.File; 

$> bash search_replace.sh 
import java.util.Scanner; 
import java.io.Exception 
import java.io.File; 

或者你也可以發出聲音的整個文件到內存中,並做了一次替換

data=$(<file) 
echo "${data/import java.io.File;/import java.io.IOException}" 
0

只需在命令行上進行如下操作:

cat text.txt | 
awk '/File/{ 
    if (count < 1){ gsub("File","IOException")} 
    count++ 
    print 
    }' 
2

當它只需要替換來完成一行中的所有工作時,肯定不需要編寫一些大的長腳本。你只需要爲這項工作選擇合適的電動工具。

這裏有一個Perl的一個班輪:

% cat -n /tmp/f 
    1 import java.lang.Character; 
    2 import java.io.File; 
    3 import java.io.File; 
    4 import java.util.Pattern; 

% perl -pe 's//IoException/ if m?import java\.io\.\KFile?' /tmp/f 
import java.lang.Character; 
import java.io.IoException; 
import java.io.File; 
import java.util.Pattern; 

如果你想與該文件的編輯做到這一點,只需添加-i.bak

% perl -i.bak -pe 's//IoException/ if m?import java\.io\.\KFile?' /tmp/f 

% head /tmp/f{,.bak} 
==> /tmp/f <== 
import java.lang.Character; 
import java.io.IoException; 
import java.io.File; 
import java.util.Pattern; 

==> /tmp/f.bak <== 
import java.lang.Character; 
import java.io.File; 
import java.io.File; 
import java.util.Pattern; 

原因這是有效的,因爲當你給m//運營商一個??定界符時,它有一些內置的狀態要記住只與第一次匹配。

然後在替代品中,空的模式意味着重用最後一次匹配的模式,因此您不必再次鍵入它,並冒險使兩者分離。

最後,模式中的\K違反了匹配,將這些東西「保持」在左邊,這樣它就不會被替換物吞噬。

2
cat file | sed -e ':l 
    0,/my_search_str/ { 
    /my_search_str/! { 
      N; 
      b l 
      } 
    s/my_search_str/replace_this/g 
    :t 
    N 
    b t  
    } 
    ' 

,這是爲我工作: 文件:(前)

hello1 
my_search_str 
hello2 
mysearch_str 
hello3 

文件:(後)

hello1 
replace_this 
hello2 
mysearch_str 
hello3 
1

我會做的就是在所有行追加偉大的路線並更換內容。

$ cat f 
import java.io.File; 
import java.io.File; 
$ sed -n 'N 
    ${ 
    s/import java.io.File;/import java.io.IOException/ 
    p 
    }' f 
import java.io.IOException 
import java.io.File; 

它是如何工作的:首先,我壓抑行打印,這是默認的行爲,傳遞-n選項的sed。

然後出現sed命令。第一個命令是N命令:它將新行和下一行添加到當前行,然後保持在模式空間。這將改變當前行到下一行,然後下一行將被追加......直到文件結束。

在文件末尾以及N命令在最後一行執行後,模式空間將包含所有行。然後,在文件的結尾(這是由$地址指定),我們只需替換具有期望行:

s/import java.io.File;/import java.io.IOException/ 

由於s///命令在默認模式空間確實每次迭代僅一個替換,它將只會取代第一行。現在圖案空間已經更換了一行,但是因爲我們使用了-n選項,所以不會打印出來。所以,我們需要用p命令打印它。一旦我們將在文件末尾執行兩個操作,我們用$來處理它,並在括號之間進行操作({})。

在那裏,爲了清晰起見,我們只是在多行中介紹了sed命令。我們可以在一行中使用它們;只是分號分隔它們:?如何用sed在文件中只替換第一次出現]

$ sed -n 'N;${s/import java.io.File;/import java.io.IOException/;p;}' f 
import java.io.IOException 
import java.io.File; 

HTH