sed 特殊字符替换在 shell 脚本中不起作用

sed 特殊字符替换在 shell 脚本中不起作用

我想编写一个脚本“test.sh”,它将接受用户的输入并用“\”+字符替换所有特殊字符。我的脚本:

#!/bin/bash
echo 'input='"$1"
arg=`echo "$1" | sed 's:[]\[\^\$\.\*\/]:\\&:g'`
echo 'modified input='"$arg"

我的命令适用于字符串“xy”,它没有任何特殊字符。我在终端中运行此命令:

test.sh xy

我得到:

input=xy
modified input=xy

但是,当我运行这个时:

test.sh x.y

我得到:

input=x.y
modified input=x&y

我不明白为什么这个脚本不起作用。我期望得到:

input=x.y
modified input=x\.y

我认为问题出在这个 sed 命令上,但我不确定在哪里:

sed 's:[]\[\^\$\.\*\/]:\\&:g'

答案1

我认为你没有正确捕获该组。尝试这个?

sed 's:\([]\[\^\$\.\*\/]\):\\\1:g'

编辑:没关系,我不知道 & 的相关性。问题是由于解析并传递到子 shell,您需要额外转义替换中的斜杠。

sed 's:[]\[\^\$\.\*\/]:\\\\&:g'

另外,如果您使用 $(command) 而不是反引号,则不需要额外的 \'s

答案2

因此,任务是编写一个替换,以转义字符串中的sed所有特殊字符(定义为字符[]^$.*/,我也添加了)。\

替换可能看起来像

s/[][\^$.*/]/\\&/g

请注意,我们实际上不必转义[...]集合中的任何字符(\也按字面意思处理,因此我们不能逃脱那里的任何东西),而我们唯一要确保的是,这]是在它的一开始。

所以脚本(重写为 shell 函数,并以其他方式修改)变成

function escape
{
    printf '%s\n' "$1" | sed 's/[][\^$.*/]/\\&/g'
}

测试:

$ escape 'hello world'
hello world

$  escape '*.*'
\*\.\* 

$ escape '\/'
\\\/

$ escape '/\'
\/\\

$ escape 's/[][\^$.*/]/\\&/g'
s\/\[\]\[\\\^\$\.\*\/\]\/\\\\&\/g

相关内容