【问题标题】:Sed error: unknown option to 's' [duplicate]Sed错误:'s'的未知选项[重复]
【发布时间】:2013-04-28 06:35:31
【问题描述】:

我在 bash 脚本中有一个 sed 命令,它将文件中的第 10 行替换为变量的值。 好的停止混淆(这是我的错,这是完整的脚本:

#!/bin/bash

#Sync timezone between system and php

##get current timezone of system
line=$(head -n 1 /etc/sysconfig/clock)    
timezone=${line:6}

##Set up php date string
time="date_default_timezone_set('${timezone%?}');"
sed -i 10s|.*|$time| test.php

所以时间的值如下:

date_default_timezone_set('欧洲/伦敦')

现在给出这些错误:

> test.php: Permission denied
> date_default_timezone_set('Europe/London);: Not such file or direcotry
> .: .:: is a directory
> sed: -e expression #1. char 3: unterminated 's' command

任何帮助都会很棒,如果您需要更多信息,请告诉我!

【问题讨论】:

  • 这会将整行替换为$time。你不是只想替换部分行,比如$timezone吗?
  • 是的,另一种选择是将行保留在 test.php 中并仅更新 $timezone 部分。我不知道该怎么做,所以只做了整条线,但如果你能做到,那就太好了
  • 这会将整行替换为$time。您的 PHP 文件中将有一行仅包含 $time。通常,这是无效的 PHP。 --哦等等,我明白了……
  • 是的 php 文件第 10 行只是 $time 这确实适合我的目的
  • 我在想 $time 是一个 PHP 变量,但它是一个 bash 变量......没关系。

标签: bash sed


【解决方案1】:
time='date_default_timezone_set\("\$timezone"\);'

请注意,我也颠倒了引号的样式。这是必要的,因为 PHP 在使用单引号时不会替换变量。

您也可以将 $time 括在引号中,但如果 $timezone 是一个实际变量,您仍然需要双引号:

time='date_default_timezone_set("$timezone");'
sed -i 10s/.*/"$time"/ test.php

根据您对问题的更新,我的理解是您实际上是在使用字符串常量代替$timezone,因此这可能不适用。在这种情况下,最干净的选择是:

time='date_default_timezone_set("America/New_York");'
sed -i 10s/.*/"${time/\//\\/}"/ test.php

请注意,这要求 bash 处于“bash”模式,而不是“sh”模式。确保在任何脚本的顶部都有 #!/bin/bash

【讨论】:

  • 嗯。我得到了奇怪的错误:sed: 1: "test.php": undefined label 'est.php' 通过运行上面的代码
  • @kobame 哪组代码?所有这些都对我有用。
  • 最后两行,sed -i 10s/.*/"${time/\//\\/}"/ test.php - 我将两者都放入文件 myscript 并以bash myscript 执行 - 我的 test.php 仅包含 20 行数字
  • nah - 刚刚解决了 - 需要 GNU sed - 使用普通的 POSIX sed 脚本无法正常工作。当用我的gsed 尝试它时,它工作的 gnu sed 是什么。你能写它吗?POSIX兼容吗?
  • Zenexer 和 @kobame - BSD sed(包括在 Mac 上)需要 -i 的参数,指定备份后缀,因此它将 10s/.../ 作为该参数,留下 test.php 作为命令;其中第一个t 被解释为标签est.php 的跳转命令,该标签不存在,导致您遇到错误。您可以通过将-i 更改为-i .bak-i '' 来解决此问题。
【解决方案2】:

不幸的是,获取时区是不可移植的,但通常 /etc/localtime 是指向您的时区的符号链接,因此您可以:

tz=$(readlink /etc/localtime | sed 's:\(.*\)/\([^/]*\)/\([^/]*\)$:\2/\3:')
echo ==$tz==

你会得到像==Europe/London== 这样的东西。现在你可以构造你的字符串了

time="date_default_timezone_set('$tz');"

并在 sed 中使用它 - 但不要使用 / 作为分隔符(因为包含它的时间刺痛并混淆您的 sed)

sed -i "10s:.*:$time:" test.php

【讨论】:

  • 如果你的字符串变成冒号会怎样?
  • 但理论上,随着代码的变化,有人可能会添加该字符。逃避一切通常是一个更好的主意。
【解决方案3】:

由于timezone 包含/ 字符,你需要做一些特别的事情:

sed -i 10s@.*@$time@ test.php

您可以使用未出现在源字符串和目标字符串中的任何字符。这里我选择了@

【讨论】:

  • 谢谢你,虽然上面所有的方法都行,这是我用的那个
猜你喜欢
  • 2016-03-19
  • 2013-03-08
  • 2014-09-02
  • 2013-06-06
  • 2012-03-11
  • 2014-12-08
  • 2014-04-06
  • 2020-11-25
相关资源
最近更新 更多