使用没有换行符的 sed append/change/insert

Using sed's append/change/insert without a newline

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

ai 命令的相同问题)

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

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

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

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

表示

$'...' 功能在 ksh93zshmksh 和 FreeBSD sh.

中也可用

TLDR

您无法控制 air 等。阿尔。他们打印 stuff + \n.

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

例子

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' 分隔命令,包括注释。
    最后一个等价的一行是 printf 'foo\nfoo' | sed -n '$!;s@\n@bar\n@;$s@$@bar@;p' | cat -A

‍♂️

提示

  • 使用脚本文件,最好在像 vim 这样的编辑器中使用 sed 语法突出显示。
#!/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
    打印当前模式-space 带有转义的特殊字符
  • 使用=
    打印当前行