sed和双引号

时间:2014-05-17 19:21:31

标签: sed escaping double-quotes

我遇到脚本问题,如果文件test.cfg不存在,那么正确的密码将写入test.cfg文件中,但如果test.cfg存在则密码不会被更改

这是我的脚本test.sh -password mysecret

#!/bin/bash
while test $# -gt 0; do
    case "$1" in
        "-password" )
        password="$2"
        shift
    ;;
    esac
shift
done

grep "password = " test.cfg &>/dev/null
if [[ $? -eq 0 ]]; then # Vorhanden!
    sed -i test.cfg -e "s/^\(password = \).\"*$/\1${password}\";/"
else # Nicht vorhanden!
    echo "password = \"${password}\";" >> test.cfg
fi

当test.cfg不存在时,将使用Content

创建
password = "mysecret";

但现在该行存在,那么密码将不会更改为test.sh -password mynewsecret

它只会变为:

password = mynewsecret;

2 个答案:

答案 0 :(得分:1)

\"*表示*双引号为零或更多次。你需要一些不同的正则表达式:

sed -e "s/^\(password = \)\".*\"$/\1\"$password\";/"

请注意case适用于有多种可能性,if更合适:

while (( $# )) ; do
    if [[ $1 == '-password' ]] ; then
        password=$2
        shift
    fi
    shift    # What does this do, anyway?
done

if grep -q 'password = ' test.cfg ; then
    sed -i~ -e "s/^\(password = \)\".*\"$/\1\"$password\";/" test.cfg
else
    echo 'password = "'"$password"'";' >> test.cfg
fi

答案 1 :(得分:0)

问题是您的替换字符串不包含您删除的双引号,并且您的代码与您的预期不符。使用此功能 - 它会将第一个\"移动到正确的位置。

sed -i -e "s/^\(password = \).*$/\1\"${password}\";/" test.cfg

顺便说一句,你必须使用GNU sed。 Mac OS X sed会抱怨sed: -i may not be used with stdin,因为它需要-i的参数,因此它会将test.cfg视为要添加到备份文件中的后缀(因此没有文件名参数,因此它从标准输入读取)。我仍然认为最好在非选项参数之前放置选项参数,即使GNU getopt(1)(或getopt_long(1))支持交错选项和非选项参数。我已经适当地重新排序了命令行。它仍然无法在Mac OS X上运行; -i那里的后缀不是可选的。