2013-02-17 66 views
1

我正在尋找使用變量搜索文件內的字符串。使用變量與grep,以及關於這個的IF語句

我有一個腳本,將接受3或4個參數:3是必需的;第四不是強制性的。

我想在同一行內搜索匹配3個參數的文本文件,如果匹配,那麼我想刪除該行並將其替換爲我的新行 - 基本上它會更新第四個參數if設置,並避免重複的條目。

目前,這是我所:

input=$(egrep -e '$domain\s+$type\s+$item' ~/etc/security/limits.conf) 

if [ "$input" == "" ]; then 

    echo $domain $type $item $value >>~/etc/security/limits.conf 

    echo \"$domain\" \"$type\" \"$item\" \"$value\" has been successfully added to your limits.conf file. 


else 
    cat ~/etc/security/limits.conf | egrep -v "$domain|$type|$item" >~/etc/security/limits.conf1 
    rm -rf ~/etc/security/limits.conf 
    mv ~/etc/security/limits.conf1 ~/etc/security/limits.conf 

    echo $domain $type $item $value >>~/etc/security/limits.conf 

    echo \"$domain\" \"$type\" \"$item\" \"$value\" has been successfully added to your limits.conf file. 
    exit 0 
fi 

現在我已經知道input=egrep等將無法正常工作;它工作如果我硬編碼一些值,但它不會接受這些變量。基本上我有domain=$1,type=$2等等。

我想它,這樣,如果所有3個變量沒有被內一個線匹配,比它只是在參數追加到文件的末尾,如果參數不匹配,那麼我想他們被刪除,並附加到文件中。我知道我可以使用其他東西,如sed和awk,但我還沒有學習它們。

這是一個學校任務,所有的幫助都非常感謝,但我也想知道爲什麼以及它是如何工作/不這樣做的,所以如果你可以提供答案,那也是大!

回答

0

你的腳本中有幾個bug。這裏是你的腳本,添加了一些註釋

input=$(egrep -e '$domain\s+$type\s+$item' ~/etc/security/limits.conf) 
    # use " not ' in the string above or the shell can't expand your variables. 
    # some versions of egrep won't understand '\s'. The safer, POSIX character class is [[:blank:]]. 

if [ "$input" == "" ]; then 
    # the shell equality test operator is =, not ==. Some shells will also take == but don't count on it. 
    # the normal way to check for a variable being empty in shell is with `-z` 
    # you can have problems with tests in some shells if $input is empty, in which case you'd use [ "X$input" = "X" ]. 

    echo $domain $type $item $value >>~/etc/security/limits.conf 
    # echo is unsafe and non-portable, you should use printf instead. 
    # the above calls echo with 4 args, one for each variable - you probably don't want that and should have double-quoted the whole thing. 
    # always double-quote your shell variables to avoid word splitting ad file name expansion (google those - you don't want them happening here!) 

    echo \"$domain\" \"$type\" \"$item\" \"$value\" has been successfully added to your limits.conf file. 
    # the correct form would be: 
    # printf '"%s" "%s" "%s" "%s" has been successfully added to your limits.conf file.\n' "$domain" "$type" "$item" "$value" 

else 
    cat ~/etc/security/limits.conf | egrep -v "$domain|$type|$item" >~/etc/security/limits.conf1 
    # Useless Use Of Cat (UUOC - google it). [e]grep can open files just as easily as cat can. 

    rm -rf ~/etc/security/limits.conf 
    # -r is for recursively removing files in a directory - inappropriate and misleading when used on a single file. 

    mv ~/etc/security/limits.conf1 ~/etc/security/limits.conf 
    # pointless to remove the file above when you're overwriting it here anyway 

    # If your egrep above failed to create your temp file (e.g. due to memory or permissions issues) then the "mv" above would zap your real file. the correct way to do this is: 
    #  egrep regexp file > tmp && mv tmp file 
    # i.e. use && to only do the mv if creating the tmp file succeeded. 

    echo $domain $type $item $value >>~/etc/security/limits.conf 
    # see previous echo comments. 

    echo \"$domain\" \"$type\" \"$item\" \"$value\" has been successfully added to your limits.conf file. 
    # ditto 

    exit 0 
    # pointless and misleading having an explicit "exit <success>" when that's what the script will do by default anyway. 

fi 
2

三件事:

  • 要指定命令,使用VAR = $(CMD)的輸出。
  • 請勿在作業中放置空格。
  • 表達式不會在單引號中展開:使用雙引號。

總結:

input=$(egrep -e "$domain\s+$type\s+$item" ~/etc/security/limits.conf) 

還要注意的〜是你的主目錄,所以如果你的意思/etc/security/limits.conf而不是/home/youruser/etc/security/limits.conf,離開落〜

+0

我是'ksh'傢伙 - 我們會使用\'yourexpression \'來做到這一點。這是否在bash中工作,或只有$()? – Joe 2013-02-17 04:26:57

+0

反引號和'$(..)'都適用於所有POSIX shell,包括'bash'和'ksh'。 '$(..)'雖然好得多,它更好地嵌套,並且具有更少的令人驚訝的逃生行爲。 – 2013-02-17 04:29:00

+0

啊,感謝您的信息! – Joe 2013-02-17 04:29:55

0

這條線:

input=$(egrep -e '$domain\s+$type\s+$item' ~/etc/security/limits.conf) 

需要在正則表達式中使用雙引號才能讓shell插入變量值。

input=$(egrep -e "$domain\s+$type\s+$item" ~/etc/security/limits.conf) 

你需要小心反斜槓;在這種情況下,你可能不需要將它們加倍,但是你應該確定你知道爲什麼。

你應該知道,你的第一個egrep命令是什麼選擇比這是用來從文件中刪除數據的第二egrep更嚴格。第一個要求在單行中輸入三個字段;第二個只需要與任何一個單詞匹配(並且可能是更大單詞的一部分)以刪除該行。

由於~/etc/security/limits.conf是一個文件,因此不需要使用rm-r選項;除非您打算刪除目錄,否則建議不要使用-r