2012-05-15 40 views
2

我正在研究一個腳本,其中包括從文件中刪除一行的腳本。要刪除的行存儲在一個變量中,並從命令行參數構建。這是我到目前爲止有:從shell中的文件中刪除完全匹配的行腳本

#!/bin/sh 
repo=$1 
devscript=/usr/local/bin/svn-post-commit-update-$repo-dev 
livescript=/usr/local/bin/svn-post-commit-update-$repo-live 
sudoer="www-data ALL=(root) NOPASSWD: $devscript, $livescript" 
sed -i '//$sudoer/ d' /home/bdugan/t.txt 

而且我收到以下錯誤:

sed: -e expression #1, char 3: unknown command: `$'

我意識到,在這一點上,我已經搞砸了一些簡單的語法問題,但對於我無法找到它的生活。有任何想法嗎?

回答

4

關鍵是您必須使用雙引號,以便變量得到擴展。否則,sed從字面上看美元符號。

另外關鍵是你的圖案包含斜槓。您必須使用備用分隔符:

sed -i "\|$sudoer|d" /home/bdugan/t.txt 

選擇一個分隔符是不太可能出現的字符串中。

+0

從雙引號開始並以單引號結尾? Naaaah!我相信逃避管道是不需要的。 – Jens

+0

@Jens:報價不匹配是一個錯字。你對分隔符是正確的。我曾認爲備用地址分隔符是GNU擴展名。 –

2

由於您的行包含/字符,因此它會混淆sed的/regex/分隔符。你可能想使用的,而不是一個正則表達式awk和使用字符串相等:

awk -v line="$sudoer" '$0 == line {next} {print}' ~/t.txt > ~/t.txt.new && 
mv ~/t.txt ~/t.txt.old && 
mv ~/t.txt.new ~/t.txt 
1

試試這個

sed -e "'[email protected]${sudoer}@@'" -e '/^$/d' -i /home/bdugan/t.txt 

這將使用@作爲分隔符是隻針對substition命令可能的,然後刪除空行。

編輯:你不得使用/作爲文件名和路徑分隔符,因爲它可能會破壞你的sed正則表達式

更新:

如果您使用GNU sed可以減少命令

sed -e "'\@${sudoer}@d'" -i /home/bdugan/t.txt 
+0

請注意,該命令將刪除文件中的每一個空行。如果這不是問題,它應該爲你工作。 – dwalter

+0

您可以將regexp重寫爲「@ $ {sudoer} @d」。 – alexander

+1

不可以,因爲'sed'不允許除替換命令之外的任何命令的替代分隔符(至少這是由'sed'的文檔說的,可能最近有變化)。你介意在你的本地機器上測試它,並告訴我它是否工作? – dwalter