未终止的“s”命令

未终止的“s”命令

我查看了其他类似的问题,但答案对我没有帮助。我是 bash 新手,我的脚本中可能有语法错误,但我不知道在哪里。我试图在每次运行此脚本时更新 example.conf 文件中的用户。每个用户都有一个 name.pub 文件。

VAR1=$( ls  | grep ".pub" |sed "s/.pub//g")
VAR2="@demo_project_users = "
res=$VAR2$VAR1
sed  "s/@demo_project_users = .*/$res/g" example.conf

这会产生Unterminated 's' command错误。

编辑:我将这些文件放在一个文件夹中

aaaaaaaaaa.pub  eboh.pub      get_usernames.sh  mmusterfrau.pub  plom.pub   rrein.pub  update_users.sh
dboh.pub        example.conf  leni.pub          mmustermann.pub  rcall.pub  tani.pub

我想将所有用户名(不带 .pub)放在一行中,中间有一个空格,如下所示

@demo_project_users = (... all  names here)

答案1

您的grep文件名可能匹配多个文件名,其中给出的值$res包含换行符。sed当使用包含文字换行符的替换字符串时,GNU会按照您所描述的方式进行抱怨。

不要用于grep过滤 的输出ls。如果您想获取当前目录中与模式匹配的所有名称*.pub,请使用

filenames=( *.pub )

这将创建一个包含与给定模式匹配的所有名称的数组。

然后:

sed 's/\(@demo_project_users = \).*/\1'"${filenames[*]%.pub}"'/g' example.conf

扩展"${filenames[*]%.pub}"将扩展为由数组中的每个文件名组成的单个字符串filenames,以空格分隔(或任何第一个字符$IFS碰巧是;默认情况下为空格),并.pub从每个文件名中删除后缀字符串。

它是"${filenames[*]}"扩展为空格分隔字符串的位,也是从每个文件名中%.pub删除后缀的位。.pub

答案2

$res命令的替换是由 shell 完成的。如果值中有斜杠,sed 无法知道它不是命令的结束标记s。同样,sed 会将任何反斜杠或 & 符号解释$res为特殊字符。

如果反斜杠和与号不可能出现,$res并且您知道另一个字符也不可能出现,请使用该字符作为分隔符。例如:

sed  "s~@demo_project_users = .*~$res~g" example.conf

或者,通过在特殊字符前添加反斜杠来引用它们。

quoted_res=$(printf %s "$res" | sed 's/[\\\/&]/\\&/g')
sed  "s/@demo_project_users = .*/$quoted_res/g" example.conf

相关内容