1

我正在寻找使用变量在文件中搜索字符串。

我有一个可以接受 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=egrepetc.. 不起作用;如果我对某些值进行硬编码,它会起作用,但它不会接受这些变量。基本上我有domain=$1type=$2等等。

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

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

4

3 回答 3

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,请不要使用 ~

于 2013-02-17T04:19:58.240 回答
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选项rm-r除非您打算删除目录,否则建议不要使用。

于 2013-02-17T04:25:24.280 回答
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
于 2013-02-17T11:57:47.323 回答