我正在尝试使用命令执行脚本:
sed -i "USER/c\export USER=${signumid}" .bashrc
sed -i "DEVENVHOME=$/c\export DEVENVHOME=${DEVENVHOME:-/home/${signumid}/CPM_WORKAREA/devenv.x}" .bashrc
我想将USER
中的字符串“.bashrc
”替换为export USER=${signumid}
,其中$signumid
变量通过Cygwin提示提供。同样,我想在DEVENVHOME=$
文件中用export DEVENVHOME=${DEVENVHOME:-/home/${signumid}/CPM_WORKAREA/devenv.x}
替换字符串.bashrc
,其中$signumid
变量通过Cygwin提示符提供。
但我在Cygwin termminal上遇到以下错误。:
sed: -e expression #1, char 1: unknown command: `U'
sed: -e expression #1, char 3: extra characters after command
答案 0 :(得分:0)
sed
脚本的一般语法是一系列地址 命令 参数语句(由换行符或分号分隔) 。最常见的命令是s
替换命令,带有一个空的地址,因此我们可以假设这就是您要在此处使用的内容。您似乎试图插入一个shell变量$signumid
,这会给这个展示添加一些复杂功能。
如果你的字符串只是静态文本,那么使用单引号是有意义的;然后,shell根本不会更改引号内的文本。 s
命令的一般语法是s/regex/replacement/
,其中作为参数分隔符的斜杠只是一个占位符,我们很快就会看到。
sed -i 's/.*USER.*/export USER=you/
s% DEVENVHOME=\$%export DEVENVHOME=${DEVENVHOME:-/home/you/CPM_WORKAREA/devenv.x}%' .bashrc
这将找到包含USER
的任何行,并用export USER=you
替换整行;然后找到任何包含DEVENVHOME=$
的行(前面有空格,以及字面的美元字符),并用长字符串替换匹配的表达式。因为替换字符串在内部使用斜杠,我们使用不同的正则表达式分隔符%
- 或者,我们可以反斜杠 - 转义不是分隔符的斜杠,但正如我们将看到的,当我们添加以下内容时,它很快变得难以维持捻。因为美元符号作为正则表达式中的“行尾”元字符具有重要意义,所以我们反斜杠 - 逃避它。
我在假设它只是对c\
语法的误解的假设中忽略了sed
。如果它很重要,你希望用它完成什么? c\export
不是有效的Bash命令,所以你可能意味着别的东西,但我不知道是什么。
现在,要将shell变量signumid
的值插入到替换中,我们不能使用单引号,因为那些禁止插值。您已经正确地尝试使用双引号(在您编辑的问题中),但这意味着我们必须进行一些额外的更改。在双引号内,反斜杠由shell处理,因此我们需要将所有反斜杠加倍,或者找到替代结构。幸运的是,对于我们来说,唯一的反斜杠是\$
,它可以等效地表示为[$]
,所以让我们改用这种符号。此外,在替换字符串中需要文字美元符号的情况下,我们反斜杠 - 转义它以防止shell处理它。
sed -i "s/.*USER.*/export USER=$signumid/
s% DEVENVHOME=[$]%export DEVENVHOME=\${DEVENVHOME:-/home/$signumid/CPM_WORKAREA/devenv.x}%" .bashrc
等效,您可以在脚本部分周围使用单引号,这些部分应该不受外壳影响,然后在需要插值的部分周围放置一个相邻的双引号字符串,例如
'un$touched*by$(the!shell)'"$signumid"'more$[complex]!stuff'
这个最后的剧本仍然依赖于一些幸运的或者可能相当不幸的猜测,关于你真正想要的东西。在第一行,我将USER
更改为与整行匹配的正则表达式 - 也许这不是您想要的?另一方面,第二行做出相反的假设,只是因为你可以看到变化 - 它只替换我们匹配的实际文本。可能需要更改其中一个。
最后,请注意两个单独的sed
命令是如何混合到一个脚本中的。许多新手没有意识到sed
是一种脚本语言,它接受脚本中的任意数量的命令,并简单地将其视为具有有趣语法的“替换”程序。
混淆的另一个常见原因是评估顺序。 shell甚至在sed
开始执行之前处理双引号字符串,因此如果引号中有错误,您可以轻松地在sed
脚本中产生语法错误,这会导致相当无法提供信息的错误消息(因为sed
在错误消息中告诉你的是基于shell的替换后脚本的样子。例如,如果signumid
包含斜杠,则会产生语法错误,因为sed
会将这些视为s///
命令的终止分隔符。一个简单的解决方法是切换到signumid
的值不会出现的分隔符。