【问题标题】:sed error - unterminated substitute patternsed 错误 - 未终止的替代模式
【发布时间】:2010-02-16 04:06:29
【问题描述】:

我在目录中,其中的文件由许多行组成,如下所示:

98.684807 :(float)
52.244898 :(float)
46.439909 :(float)

然后一行结束:

[chuck]: cleaning up...

我正在尝试从每个文件中删除:(float)(但留下数字),并删除清理...行。

我可以得到:

sed -ie 's/ :(float)//g' *

工作,但这会创建保留旧文件的文件。删除 -e 标志会导致未终止的替换模式错误。

同样处理:

sed -ie 's/[chuck]: cleaning up...//g' *

想法?

【问题讨论】:

  • “创建保留旧文件的文件”是什么意思?
  • 如果我有一个名为 abc.它从文件 abc 中删除行,但创建一个名为 abce 的文件。
  • 如果模式每行只出现一次,则不需要g
  • 我知道我迟到了,但sed -ie 's/ :(float)//g' *sed -ie 's/[chuck]: cleaning up...//g' * 可能不会像你期望的那样做; (float) 周围的()[float] 周围的[],以及cleaning up... 中的... 都是特殊模式。使用sed -ie 's/ :(float)//g' *,它也可能匹配:float。对于sed -ie 's/[chuck]: cleaning up...//g' *,它不会匹配[chuck]: cleaning up...,但会匹配k: cleaning up123

标签: sed


【解决方案1】:
sed  -i  ''  -e  's/:(float)//'  -e  '/^.chuck/d'  *

这样你告诉 sed 不要保存副本(空长度备份扩展至-i)并单独指定 sed 命令。

【讨论】:

  • 对于收到错误“未终止的转换源字符串”的人来说,这也是有效的答案。在某些版本的 sed(尤其是 macOS 中包含的 BSD 版本)上,当您不想让 sed 进行备份时,您必须在 -i 之后显式包含空字符串 '',在其他平台上,您可以保留它出去。不幸的是,在需要时 sed 输出的错误消息非常神秘。
【解决方案2】:
sed -ie expression [files...]

相当于:

sed -ie -e expression [files...]

两者都表示将表达式应用于文件,覆盖文件,但以“e”作为备份后缀保存旧文件。

我想你想要: sed -i -e 表达式 [文件...]

现在,如果您收到错误消息,则您的 expression 一定有问题。

【讨论】:

    【解决方案3】:

    您的号码由(float) 分隔,并由: 字符分隔。因此,您可以使用 awk/cut 来获取您的数字。它比正则表达式更简单

    $ head -n -1  file | awk -F":" '{print $1}'
    98.684807
    52.244898
    46.439909
    
    $ head -n -1  file | cut -d":" -f1
    98.684807
    52.244898
    46.439909
    

    【讨论】:

      【解决方案4】:

      解决方案:

      sed -i '' 's/ :(float)//g' *

      sed -i '' 's/[chuck]: cleaning up...//g' *

      说明:

      我可以得到:

      sed -ie 's/ :(float)//g' *
      

      可以工作,但这会创建保留旧文件的文件。

      那是因为 sedi 标志应该以这种方式工作

      -i 扩展

      就地编辑文件,使用指定的扩展名保存备份。如果给出一个零长度的扩展名,则不会保存备份。

      在这种情况下,e 被解释为您要用来保存备份的扩展名。因此,您的所有原始文件都将在其名称后附上e 进行备份。

      为了提供零长度扩展,您需要使用-i ''

      注意:与-i<your extension> 不同,-i'' 不起作用。您需要在-i'' 之间有一个空格字符,它才能工作。


      删除 -e 标志会导致未终止的替换模式错误。

      当您删除紧跟在-i 之后的e 时,即

      sed -i 's/ :(float)//g' *

      s/ :(float)//g 现在将被解释为 i 标志的 extension 参数。 * 的 shell 扩展产生的文件列表中的第一个文件被解释为 sed function(很可能是 s/regular expression/replacement/flags 函数)您可以通过检查输出来验证这一点

      sedfn=$(echo * | cut -d' ' -f1); [[ ${sedfn:0:1} == "s" ]]; echo $?

      如果上述命令链的输出为0,则我们的假设得到验证。

      同样在这种情况下,如果第一个文件名以某种方式符合有效的s/regular expression/replacement/flags sed 函数,则其他文件名将被解释为常规文件以供 sed 操作。

      【讨论】:

        【解决方案5】:
        sed -i -e 's/ :(float)//g' *
        

        【讨论】:

          【解决方案6】:

          检查目录中是否有任何奇怪的文件名。

          这是复制错误的一种方法:

          $ touch -- "-e s:x:"
          $ ls
          -e s:x:
          $ sed -i "s/ :(float)//g' *
          sed: -e expression #1, char 5: unterminated `s' command
          

          防止这种情况的一种方法是在使用通配符时使用双破折号终止sed 的选项:

          $ sed -i "s/ :(float)//g' -- *
          

          你可以做同样的事情来删除文件:

          $ rm "-e s:x:"
          rm: invalid option -- 'e'
          $ rm -- "-e s:x:"
          

          【讨论】:

            猜你喜欢
            • 2019-02-15
            • 2018-03-22
            • 1970-01-01
            • 2012-05-05
            • 1970-01-01
            • 2021-06-26
            • 2020-12-14
            • 2011-05-03
            • 1970-01-01
            相关资源
            最近更新 更多