2012-11-08 43 views
2

我有很多行的文件,其中兩個是:替換字符串或者用grep

videoId: 'S2Rgr6yuuXQ' 

var vid_seq=1; 
在shell腳本

,我有兩個變量, 的ID,值總是11個字符/數字

ID = 'fsafsferii2'

id_seq = 80

我想修改這兩行具有ID和id_seq

videoId: 'fsafsferii2' 

var vid_seq=80; 

我用

​​

,但有錯誤,有什麼不對我的腳本?

感謝

+2

有什麼錯誤? – ghoti

+0

sed:-e表達式#1,字符33:未終止的's'命令 – user1769686

+1

對。您正在使用'/'作爲您的替換的分隔符。該命令是's/pattern/replacement /',你錯過了最後的分隔符。這就是「未終止」的意思。 – ghoti

回答

3

grep命令不會「取代」的文字,它是「全球正則表達式打印」。但sed會。

sed -i'' '/^videoId: /s/: .*/: '"$id"'/;/^var vid_seq=/s/=.*/='"$id_seq"';/' 

我不把各種變量納入sed腳本這樣的大風扇,但sed的簡單,沒有提供機制,實際使用它自己的實際變量。如果要這樣做,請在運行此sed腳本之前,包含一些格式檢查兩個變量,以確保它們包含希望它們包含的數據。變量中偶然的/會導致sed腳本失敗。

UPDATE每評論:

這裏有一個成功的測試:

$ id=fsafsferii2 
$ id_seq=80 
$ cat inp686 

videoId: 'S2Rgr6yuuXQ' 

var vid_seq=1; 

$ sed '/^videoId: /s/: .*/: '"$id"'/;/^var vid_seq=/s/=.*/='"$id_seq"';/' < inp686 

videoId: fsafsferii2 

var vid_seq=80; 

$ 

當然,你需要做一些報價魔術拿到單引號到您的視頻ID,但我我確定你可以自己弄清楚。

更新2

根據的sed的手冊頁,替換命令的格式爲:

 [2addr]s/regular expression/replacement/flags 

[2addr]意味着你可以指定最多兩個「地址」,它可以是線數字或正則表達式匹配。因此s(替代)命令可以在匹配之間佔用一行,一個範圍,一個匹配或一個範圍。在我們的例子中,我們只是使用單個匹配來確定我們想要執行替換的行。

上面的腳本由兩個sed命令組成,用分號分隔。

  • /^videoId: / - 比賽線路以單詞videoId:開始......
    • s/: .*/: '"$id"'/; - 代替從結腸中的所有文本與無論是在$id環境變量的行的末尾。
  • /^var vid_seq=/ - 匹配...... meh,如上所示。
    • s/=.*/='"$id_seq"';/ - 用$id_seq替代等號中的所有文字。

注意,'"$id"'結構意味着我們退出單引號,然後立即進入報價變量的擴張......然後退出雙引號中去回一套新的單引號。 Sed腳本在單引號內最安全,因爲頻繁使用可能由shell解釋的字符。

還請注意,因爲sed的替代命令使用正斜槓作爲分隔符,所以$id$id_seq變量可能不包含斜線。如果可能的話,你可以切換到不同的分隔符。

+0

你的腳本不起作用 – user1769686

+0

適用於我在測試環境中工作的基於你的問題創建的。如果您已經嘗試過並獲得不同的錯誤,請[更新您的問題](http://stackoverflow.com/posts/13288963/edit)並顯示結果。不要忘記顯示你的實際變量。如果我無法重現您的錯誤,我無法修復它。 – ghoti

+0

啊,我在videoId前修改了^ - >。* coz,裏面有很多空字符,現在就OK了。順便說一句,你能解釋一下腳本 – user1769686

1

什麼是錯的:

​​
  1. 缺少第三個分隔符(/)。有效語法是s/regex/replace/
  2. 不正確的正則表達式(假設${id}已取代)

    \(videoId: \).*\\1fsafsferii2 
    

    告訴它匹配的字符串,看起來像這樣:

    videoId: anything\1fsafsferii2 
    

    \\在正則表達式匹配文字反斜槓,所以\\1將匹配文字反斜槓後跟1而不是第一個子表達式)

  3. \2

    更換匹配的字符串,但由於只有一組括號,\2實際上是空的。

    此外,由於2.中的正則表達式模式不匹配任何東西,所以沒有被替換。


這應該工作(GNU SED)

sed -i 's/\(videoId: \).*/\1 \x27'${id}'\x27/ 
     s/\(var vid_seq=\).*/\1'${id_seq}'\;/' file 

注:

  • \x27是單引號的十六進制表示(以防止與其他單引號衝突)
  • \;用於文字分號。如果;未被轉義,則它被解釋爲在sed中終止s命令。
+0

'\ x27'不適合我。當我回應你好| sed's/e/\ x26 /'',結果是'hx26llo'。 – Graham

+0

我的猜測是一些舊版本的sed不支持這種十六進制表示法。 – doubleDown

+0

這是FreeBSD 9.1-RC3中的sed。我在OSX Mountain Lion中獲得了相同的行爲。也許你正在運行一個非標準的sed。 – Graham