Shell Sed和转义单引号
我对sed和单引号有问题 我有这样一个字符串:Shell Sed和转义单引号,shell,sed,ksh,Shell,Sed,Ksh,我对sed和单引号有问题 我有这样一个字符串: -cmd af -i 3 -a 我想把这个字符串改为 -cmd 'af -i 3 -a' 现在我用这个: 该字符串存储在buff变量中 buff=$(echo $buff | sed -r "s/cmd /CMD '/g")"'" 它回显ok-cmd'af-i3-a' 然后我用buff作为参数调用一个函数,在用ksh-x执行脚本时,我可以看到调用是NOK + buff=$'-CMD \'af -i 3 -a \'' + echo -CMD $
-cmd af -i 3 -a
我想把这个字符串改为
-cmd 'af -i 3 -a'
现在我用这个:
该字符串存储在buff变量中
buff=$(echo $buff | sed -r "s/cmd /CMD '/g")"'"
它回显ok-cmd'af-i3-a'
然后我用buff作为参数调用一个函数,在用ksh-x执行脚本时,我可以看到调用是NOK
+ buff=$'-CMD \'af -i 3 -a \''
+ echo -CMD $'\'af' -i 3 -a $'\''
-CMD 'af -i 3 -a' #this is the echo
+ functionTest -CMD $'\'af' -i 3 -a $'\''
因此,它将永远给我
-CMD $'\'af' -i 3 -a $'\''
所以基本上我的单引号被解释为$'\''
我不知道为什么,我尝试了很多方法,比如逃逸chars,但它给了我完全相同的结果,即使是
\x27
你如何看待这个奇怪的结果
您所得到的原始数据是正常的(sed
在Mac OS X上不支持-r
,但所使用的正则表达式不需要非标准GNU扩展选项-r
):
我怀疑您的问题不在于转换,而在于您查看结果的方式
ksh试验 输出正确;跟踪有点混乱,但与您显示的相同
-x
输出的额外工作有很好的理由;它消除了输出的歧义,以便您能够准确地确定什么是什么,如果您能够足够好地阅读它的话。此外,您还可以在+
之后复制“n”粘贴行,然后运行它,再次获得完全相同的结果。旧的Bourne shell有一个-x
选项,它没有像这样进行字符映射,这可能会导致混淆,并且您肯定无法可靠地复制“n”粘贴跟踪输出以再次执行命令
关键的一点是,结果——所反映的——是你想要和期望的,所以你什么都不担心(正如它所发生的那样)。但我同意,一开始可能会让人困惑。你是如何看待这个奇怪的结果的 您所得到的原始数据是正常的(
sed
在Mac OS X上不支持-r
,但所使用的正则表达式不需要非标准GNU扩展选项-r
):
我怀疑您的问题不在于转换,而在于您查看结果的方式
ksh试验 输出正确;跟踪有点混乱,但与您显示的相同
-x
输出的额外工作有很好的理由;它消除了输出的歧义,以便您能够准确地确定什么是什么,如果您能够足够好地阅读它的话。此外,您还可以在+
之后复制“n”粘贴行,然后运行它,再次获得完全相同的结果。旧的Bourne shell有一个-x
选项,它没有像这样进行字符映射,这可能会导致混淆,并且您肯定无法可靠地复制“n”粘贴跟踪输出以再次执行命令
关键的一点是,结果——所反映的——是你想要和期望的,所以你什么都不担心(正如它所发生的那样)。但我同意,一开始可能会让人困惑。这对我来说也很好。但是没有必要使用
sed
;bash内置软件可以很好地做到这一点:
$ buff='-cmd af -i 3 -a'
$ buff=${buff/cmd /CMD \'}\'
$ echo $buff
-CMD 'af -i 3 -a'
对我来说也很好。但是没有必要使用
sed
;bash内置软件可以很好地做到这一点:
$ buff='-cmd af -i 3 -a'
$ buff=${buff/cmd /CMD \'}\'
$ echo $buff
-CMD 'af -i 3 -a'
我认为@gniourf_gniourf关于在变量中存储字符串的最初评论基本上是正确的(尽管您只尝试存储命令参数);看 现在,你有两个困惑。首先,您误解了
-x
模式打印的内容。它不会打印您正在运行的命令的参数,而是打印一个将传递相同参数的命令。在本例中,一些参数包含单引号,因此它提供了一个带引号的转义字符串,在删除引号后,该字符串将导致实际传递的参数相同。例如,其中一个参数是'af
,因此-x模式将其显示为$'\'af'
其次,看起来您正在尝试在变量中嵌入单引号,以便可以将几个单词作为单个参数传递给functionTest(即,您正在尝试运行与functionTest-CMD'af-i3-a'等效的函数)。如果我对你想做的事情的看法是正确的,那你就大错特错了。当shell解析命令行时,它解释引号和转义,*然后*替换变量。它将返回并将替换的变量拆分为单词,但不会返回并注意替换文本中的引号和转义。因此,当它将
$buff替换为
-CMD'af-i3-a``时,它将其拆分为5个参数:“-CMD”、“'af”、“-i”、“3”和“-a”。请注意,单引号被视为第二个和第五个参数的一部分,而不是包含一个长参数:
$ buff="-CMD 'af -i 3 -a'"
$ printargs $buff
Got 5 arguments:
«-CMD»
«'af»
«-i»
«3»
«-a'»
为了存储多个参数而不产生这种混乱,您需要使用数组(同样,请参阅@gniourf_gniourf的注释和):
顺便说一句,如果你想复制这个,你需要printargs。我写了一个非常简单的shell脚本来澄清如下情况:
#!/bin/sh
echo "Got $# arguments:"
for arg; do
echo " «${arg}»"
done
我认为@gniourf_gniourf关于在变量中存储字符串的最初评论基本上是正确的(尽管您只尝试存储命令参数);看 现在,你有两个困惑。首先,您误解了
-x
模式打印的内容。它不会打印您正在运行的命令的参数,而是打印一个将传递相同参数的命令。在本例中,一些参数包含单引号,因此它提供了一个带引号的转义字符串,在删除引号后,该字符串将导致实际传递的参数相同。例如,其中一个参数是'af
,因此-x模式将其显示为$'\'af'
其次,看起来您正试图在变量中嵌入单引号,以便可以将多个单词作为单个参数传递给functionTest(即,您正在尝试运行与functionTest-CM等效的函数)
$ buff=(-CMD 'af -i 3 -a')
$ printargs "${buff[@]}"
Got 2 arguments:
«-CMD»
«af -i 3 -a»
#!/bin/sh
echo "Got $# arguments:"
for arg; do
echo " «${arg}»"
done