首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在sed中插入linefeed (Mac )

在sed中插入linefeed (Mac )
EN

Stack Overflow用户
提问于 2011-05-24 14:05:49
回答 8查看 50.6K关注 0票数 46

如何在sed的替换部分插入换行符?

此代码不起作用:

代码语言:javascript
复制
sed "s/\(1234\)/\n\1/g" input.txt > output.txt

其中input.txt是:

代码语言:javascript
复制
test1234foo123bar1234

output.txt应该是:

代码语言:javascript
复制
test
1234foo123bar
1234

但我明白了:

代码语言:javascript
复制
testn1234foo123barn1234

注:

这个问题专门针对Mac版本的"sed",社区注意到它的行为与Linux版本不同。

EN

回答 8

Stack Overflow用户

回答已采纳

发布于 2011-05-24 14:44:03

您的sed版本显然不支持RHS中的\n (替换的右侧)。您应该阅读Eric维护的SED常见问题,以选择可能的解决方案之一。我建议先尝试插入文字换行符。

下面是它的引文。

4.1.如何在替换的RHS中插入换行符?

有些版本的sed允许将\n直接输入到RHS中,然后将RHS转换为输出时的换行符: sed、gsed302a+、gsed103 (带有-x开关)、sed15+、sedmod和UnixDOS sed。最简单的解决方案是使用其中一个版本。

对于sed的其他版本,请尝试以下方法之一:

(a)如果从Bourne键入sed脚本,如果脚本使用‘单引号’,则使用一个反斜杠\,如果脚本需要“双引号”,则使用两个反斜杠\\。在下面的示例中,请注意,第2行的前导>是由shell生成的,以提示用户输入更多内容。用户输入斜杠、单引号,然后输入以终止命令:

代码语言:javascript
复制
 [sh-prompt]$ echo twolines | sed 's/two/& new\
 >/'
 two new
 lines
 [bash-prompt]$

(b)使用脚本文件,脚本中有一个反斜杠\,后面紧跟一个换行符。这将在“替换”部分中嵌入一个换行符。示例:

代码语言:javascript
复制
 sed -f newline.sed files

 # newline.sed
 s/twolines/two new\
 lines/g

有些版本的sed可能不需要尾随反斜杠。如果是的话,就把它移除。

(c)插入一个未使用的字符并通过tr传输输出:

代码语言:javascript
复制
 echo twolines | sed 's/two/& new=/' | tr "=" "\n"   # produces
 two new
 lines

(d)使用G命令:

G在模式空间的末尾追加一个换行符,加上持有空间的内容。如果持有空间为空,则无论如何都会追加换行符。换行符以\n的形式存储在模式空间中,在那里可以通过分组\(...\)来寻址并移动到RHS中。因此,要更改前面使用的"twolines“示例,可以使用以下脚本:

代码语言:javascript
复制
 sed '/twolines/{G;s/\(two\)\(lines\)\(\n\)/\1\3\2/;}'

(e)插入整行,而不是拆分线:

如果一个人不是在改变行,而只是在一个模式之前或之后插入完整的行,那么这个过程就容易多了。使用i (插入)或a (追加)命令,通过外部脚本进行更改。若要在匹配正则表达式的每一行之前插入This line is new,请执行以下操作:

代码语言:javascript
复制
 /RE/i This line is new               # HHsed, sedmod, gsed 3.02a
 /RE/{x;s/$/This line is new/;G;}     # other seds

上面的两个示例是从控制台输入的“一行”命令。如果使用sed脚本,则i\后面紧跟文字换行符将适用于sed的所有版本。此外,命令s/$/This line is new/只在持有空间已经为空(默认情况下为空)时才能工作。

若要在匹配正则表达式的每一行后面追加This line is new,请执行以下操作:

代码语言:javascript
复制
 /RE/a This line is new               # HHsed, sedmod, gsed 3.02a
 /RE/{G;s/$/This line is new/;}       # other seds

若要在匹配正则表达式的每一行后面追加2行空白行:

代码语言:javascript
复制
 /RE/{G;G;}                    # assumes the hold space is empty

若要用5行空行替换匹配正则表达式的每一行,请执行以下操作:

代码语言:javascript
复制
 /RE/{s/.*//;G;G;G;G;}         # assumes the hold space is empty

如果可能的话,(f)使用y///命令:

在某些Unix版本的sed (不是GNU!)上,尽管s///命令在RHS中不接受\n,但y///命令确实接受。如果Unix支持它,可以以这种方式插入aaa后的换行符(不能移植到GNU或其他sed ):

代码语言:javascript
复制
 s/aaa/&~/; y/~/\n/;    # assuming no other '~' is on the line!
票数 63
EN

Stack Overflow用户

发布于 2011-05-24 14:43:42

solaris版本的sed I可以说服您这样做(在bash中):

代码语言:javascript
复制
echo test1234foo123bar1234 | sed 's/\(1234\)/\
\1/g'

(你必须在反斜杠后直接放断线)。

csh中,我不得不再加一个反斜杠:

代码语言:javascript
复制
echo test1234foo123bar1234 | sed 's/\(1234\)/\\
\1/g'

Gnu版本的sed简单地使用\n

代码语言:javascript
复制
echo test1234foo123bar1234 | sed 's/\(1234\)/\n\1/g'
票数 9
EN

Stack Overflow用户

发布于 2011-05-24 14:29:14

Perl提供了更丰富的“扩展”regex语法,在这里很有用:

代码语言:javascript
复制
perl -p -e 's/(?=1234)/\n/g'

意思是“按照模式1234替换零宽度匹配的换行符”。这避免了使用反向引用捕获和重复表达式的部分。

票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6111679

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档