【问题标题】:Using sed's append/change/insert without a newline在没有换行符的情况下使用 sed 的追加/更改/插入
【发布时间】:2016-12-27 17:57:58
【问题描述】:

我想在 SED 中替换我的模式空间。我可以用s/^.*$/hello world/; 做到这一点 - 但我可以用c 命令以某种方式做到这一点 - 在我的 sed 脚本中不使用换行符吗?我不完全清楚这是否有可能。

ai 命令的问题相同)

【问题讨论】:

标签: sed text-processing


【解决方案1】:

如果您的 shell 是 bash,这里有一种在单行中使用 c 的便捷方法:

$ seq 3 | sed $'/2/c\\\nNew Text'
1
New Text
3

这会查找包含2 的任何行并将其更改为New Text

这使用 bash 的 $'...' 功能在字符串中输入换行符。换行符由\n 表示。 c 后面需要的反斜杠用\\ 表示。

$'...' 功能也可用于ksh93zshmksh 和 FreeBSD sh

【讨论】:

    【解决方案2】:

    TLDR

    您无法控制a,i,r 等。人。他们打印stuff + \n

    相反,使用s 修改模式空间并使用P 打印模式空间直到,不包括换行符,以获得所需的结果。

    示例

    printf 'foo\nfoo' | sed -n 'P' | cat -A
    
    foo$
    foo
    

    a/i 不起作用

    printf 'foo\nfoo' | sed -n '
    #print pattern-space wo. newline
    P
    # apppend the char F
    aF
    ' | cat -A
    
    foo$
    F$
    foo$
    F$
    

    我相信它的工作方式类似于r/R。它在循环之后附加,并且总是带有换行符。

    但您始终可以将Ns 一起使用。即。

    printf 'foo\nfoo' | sed -n -e '
    # append \n + nextline wo. its \n to pattern-space
    N
    ' -e '
    # replace the 1st \n with bar (append without trailing \n)
    s@\n@bar@
    ' -e '
    # print pattern-space up until, excluding \n
    P
    ' | cat -A
    
    foo$
    bar$
    foo$
    bar
    
    printf 'foo\nfoo' | sed -n -e '
    # expect last-line, append \n and read next-line
    $! {
      N
    }
    ' -e '
    # replace \n with bar \n
    s@\n@bar\n@
    ' -e '
    # on last line ($), append bar wo. new-line
    $ { 
      s@$@bar@
    }
    ' -e '
    # print pattern-space in its entirety
    p
    ' | cat -A
    
    foobar$
    foobar
    

    注意

    • 示例使用 cat -A 在输出中显示换行符 ($)
    • 我使用@ 作为s 的分隔符。这是个人的,可能是愚蠢的偏好。如果你愿意,它可以是标准的/|þ
    • 为了便于阅读,我使用 -e 'cmd' 分隔了命令,包括 cmets。
      最后一个等价的单线是printf 'foo\nfoo' | sed -n '$!;s@\n@bar\n@;$s@$@bar@;p' | cat -A

    ?‍♂️

    提示

    • 使用脚本文件,最好使用带有sed 语法突出显示的vim 等编辑器。
    #!/bin/sed -f
    
    # expect last-line, append \n and read next-line
    $! {
      N
    }
    # replace \n with bar \n
    s@\n@bar\n@
    # on last line ($), append bar wo. new-line
    $ { 
      s@$@bar@
    }
    # print
    p
    

    调试

    • 使用l
      使用转义的特殊字符打印当前模式空间
    • 使用=
      打印当前行

    【讨论】:

      猜你喜欢
      • 2015-01-15
      • 2021-02-16
      • 1970-01-01
      • 2011-09-25
      • 2011-02-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多