我希望使用变量在文件中搜索字符串。
我有一个接受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=$1
,type=$2
等等。
我希望如果所有3个变量在 one 行中都不匹配,那么它只会将参数附加到文件的末尾,但是如果参数匹配,然后我希望它们被删除,并附加到文件。我知道我可以使用其他东西,比如sed和awk,但我还没有学习它们。
这是一个学校作业,非常感谢所有的帮助,但我也想了解它为什么以及如何工作/没有,所以如果你能提供答案,那将是伟大的!
答案 0 :(得分:2)
三件事:
总结:
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