使用没有换行符的 sed append/change/insert
Using sed's append/change/insert without a newline
我想在 SED 中替换我的模式 space。我可以用 s/^.*$/hello world/;
做到这一点 - 但我可以用 c
命令以某种方式做到这一点 - 而不是在我的 sed 脚本中使用换行符吗?我不太清楚这是否可行。
(a
和 i
命令的相同问题)
如果您的 shell 是 bash,这里有一种在单行中使用 c
的便捷方法:
$ seq 3 | sed $'/2/c\\nNew Text'
1
New Text
3
这将查找任何包含 2
的行并将其更改为 New Text
。
这使用 bash 的 $'...'
功能在字符串中输入换行符。换行符用\n
表示。 c
后所需的反斜杠由 \
.
表示
$'...'
功能在 ksh93
、zsh
、mksh
和 FreeBSD sh
.
中也可用
TLDR
您无法控制 a
、i
、r
等。阿尔。他们打印 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
。它在循环之后追加并始终使用换行符。
但您始终可以使用 N
和 s
。即
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 带有转义的特殊字符
- 使用
=
打印当前行
我想在 SED 中替换我的模式 space。我可以用 s/^.*$/hello world/;
做到这一点 - 但我可以用 c
命令以某种方式做到这一点 - 而不是在我的 sed 脚本中使用换行符吗?我不太清楚这是否可行。
(a
和 i
命令的相同问题)
如果您的 shell 是 bash,这里有一种在单行中使用 c
的便捷方法:
$ seq 3 | sed $'/2/c\\nNew Text'
1
New Text
3
这将查找任何包含 2
的行并将其更改为 New Text
。
这使用 bash 的 $'...'
功能在字符串中输入换行符。换行符用\n
表示。 c
后所需的反斜杠由 \
.
$'...'
功能在 ksh93
、zsh
、mksh
和 FreeBSD sh
.
TLDR
您无法控制 a
、i
、r
等。阿尔。他们打印 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
。它在循环之后追加并始终使用换行符。
但您始终可以使用 N
和 s
。即
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 带有转义的特殊字符 - 使用
=
打印当前行