【问题标题】:sed escape user input string [duplicate]sed转义用户输入字符串[重复]
【发布时间】:2016-04-10 21:51:48
【问题描述】:

我在配置文件中使用 sed 进行字符串替换。

用户必须输入字符串salt,然后我在配置文件中替换这个salt字符串:

Sample config file myconfig.conf

CONFIG_SALT_VALUE=SOME_DUMMY_VALUE

我使用该命令将虚拟值替换为用户输入的值salt

sed -i s/^CONFIG_SALT_VALUE.*/CONFIG_SALT_VALUE=$salt/g" ./myconfig.conf

问题$salt 的值可以包含任何字符,所以如果$salt 包含/(如12d/dfs),那么我上面的 sed 命令会中断。

我可以将分隔符更改为!,但现在如果$salt 包含amgh!fhf,那么我的 sed 命令将中断。

我应该如何处理这个问题?

【问题讨论】:

    标签: regex bash awk sed


    【解决方案1】:

    You can use almost any character as sed delimiter。但是,正如您在问题中提到的那样,不断改变它是脆弱的。

    也许改用awk 是有用的,对行做一点解析:

    awk 'BEGIN{repl=ARGV[1]; ARGV[1]=""; FS=OFS="="}
         $1 == "CONFIG_SALT_VALUE" {$2=repl}
         1' "$salt" file
    

    作为一个班轮:

    awk 'BEGIN{repl=ARGV[1]; ARGV[1]=""; FS=OFS="="} $1 == "CONFIG_SALT_VALUE" {$2=repl}1' "$salt" file
    

    这会将= 设置为字段分隔符。然后,它检查一行何时包含CONFIG_SALT_VALUE 作为参数名称。发生这种情况时,它会将值替换为给定的值。

    为了防止 $salt 中的值(如 foo\\bar)被解释,正如其他人在我的原始答案中评论的那样,我们有诀窍:

    awk 'BEGIN{repl=ARGV[1]; ARGV[1]=""} ...' "$var" file
    

    这使用了How to use variable including special symbol in awk? Ed Morton 所说的答案

    在不使用反斜杠的情况下将 shell 变量传递给 awk 的方法 解释是将它传递到 arg 列表中,而不是填充 awk 脚本之外的变量。

    然后

    您需要在填充 awk 变量后设置ARGV[1]="" 避免 shell 变量值也被视为文件名。 与任何其他传入变量的方式不同,所有使用的字符 以这种方式对变量进行字面处理,没有“特殊”含义。

    这不会进行就地编辑,但您可以重定向到另一个文件,然后替换原始文件:

    awk '...' file > tmp_file && mv tmp_file file
    

    【讨论】:

    • awk 确实是这个 +1 的更好工具
    • 在 GNU awk 上,如果 salt='foo\\bar' 会失败
    • @thatotherguy 经过一番研究,我找到了解决方案!埃德莫顿像往常一样放了一些光:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-17
    • 2011-01-05
    • 1970-01-01
    • 2013-09-22
    • 2019-09-17
    • 2013-02-08
    相关资源
    最近更新 更多