使用带有grep的变量和关于此的IF语句

时间:2013-02-17 03:50:31

标签: bash variables grep

我希望使用变量在文件中搜索字符串。

我有一个接受3或4个参数的脚本:3个是必需的;第四个不是强制性的。

我想在文本文件中搜索同一行中匹配的3个参数,如果它们匹配,那么我想删除该行并将其替换为我的新行 - 基本上它会更新第4个参数如果设置,并避免重复输入。

目前这就是我所拥有的:

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=$1type=$2等等。

我希望如果所有3个变量在 one 行中都不匹配,那么它只会将参数附加到文件的末尾,但是如果参数匹配,然后我希望它们被删除,并附加到文件。我知道我可以使用其他东西,比如sed和awk,但我还没有学习它们。

这是一个学校作业,非常感谢所有的帮助,但我也想了解它为什么以及如何工作/没有,所以如果你能提供答案,那将是伟大的!

3 个答案:

答案 0 :(得分: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,请不要使用〜

答案 1 :(得分: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是一个文件,因此无需使用-r的{​​{1}}选项;除非您打算删除目录,否则建议不要使用rm

答案 2 :(得分:0)

您的脚本中有几个错误。这是您添加了一些评论的脚本

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