在没有换行符的情况下使用 sed 的追加/更改/插入

Posted

技术标签:

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

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

ai 命令的问题相同)

【问题讨论】:

Sed: Using a,c or i in a one-liner的可能重复 【参考方案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 使用转义的特殊字符打印当前模式空间 使用= 打印当前行

【讨论】:

以上是关于在没有换行符的情况下使用 sed 的追加/更改/插入的主要内容,如果未能解决你的问题,请参考以下文章

sed 中如何替换换行符

sed多行模板替换

sed 去掉所有的换行符

sed 去掉所有的换行符

七.sed多行模式和循环

Sed文本处理工具