如何\n
使用sed命令替换换行符()?
我没试成功:
sed 's#\n# #g' file
sed 's#^$# #g' file
Run Code Online (Sandbox Code Playgroud)
我如何解决它?
dmc*_*kee 1640
使用sed
呢?
tr '\n' ' ' < input_filename
Run Code Online (Sandbox Code Playgroud)
或完全删除换行符:
tr -d '\n' < input.txt > output.txt
Run Code Online (Sandbox Code Playgroud)
或者如果你有GNU版本(有很长的选项)
tr --delete '\n' < input.txt > output.txt
Run Code Online (Sandbox Code Playgroud)
Zso*_*kai 1434
在GNU中使用此解决方案sed
:
sed ':a;N;$!ba;s/\n/ /g' file
Run Code Online (Sandbox Code Playgroud)
这将在循环中读取整个文件,然后用空格替换换行符.
说明:
:a
.N
.$!ba
($!
意味着不要在最后一行执行,因为应该有一个最终换行符).这是与BSD和OS X一起使用的跨平台兼容语法sed
(根据@Benjie评论):
sed -e ':a' -e 'N' -e '$!ba' -e 's/\n/ /g' file
Run Code Online (Sandbox Code Playgroud)
如您所见,使用sed
这个简单的问题是有问题的.有关更简单和适当的解决方案,请参阅此答案.
hdo*_*rio 463
快速回答:
sed ':a;N;$!ba;s/\n/ /g' file
Run Code Online (Sandbox Code Playgroud)
sed将遍历步骤1到3,直到它到达最后一行,让所有行都适合模式空间,其中sed将替换所有\n字符
替代方案:
与sed不同,所有替代方案都不需要到达最后一行来开始该过程
用bash,慢
while read line; do printf "%s" "$line "; done < file
Run Code Online (Sandbox Code Playgroud)
用perl,sed- like速度
perl -p -e 's/\n/ /' file
Run Code Online (Sandbox Code Playgroud)
使用tr,比sed快,只能替换为一个字符
tr '\n' ' ' < file
Run Code Online (Sandbox Code Playgroud)
与粘贴,TR般的速度,可以用一个字符替换只
paste -s -d ' ' file
Run Code Online (Sandbox Code Playgroud)
用awk,tr- like速度
awk 1 ORS=' ' file
Run Code Online (Sandbox Code Playgroud)
其他替代方法如"echo $(<file)"很慢,仅适用于小文件,需要处理整个文件才能开始进程.
来自sed FAQ 5.10的长篇答案:
5.10.为什么我不能使用\n转义
序列匹配或删除换行符?为什么我不能使用\n匹配2行或更多行?
\n将永远不会匹配行尾的换行符,因为
在将行放入
模式空间之前始终会删除换行符.要在模式空间中获得2行或更多行,请使用
"N"命令或类似的命令(例如"H; ...; g;").
Sed的工作方式如下:sed一次读取一行,删除
终止换行符,将剩下的内容放入
sed脚本可以解决或更改它的模式空间
中,打印模式空间时,向stdout添加换行符(或文件).如果
使用"d"或"D"完全或部分删除模式空间,则在这种情况下不会添加
换行符.因此,脚本就像
sed 's/\n//' file # to delete newlines from each line
sed 's/\n/foo\n/' file # to add a word to the end of each line
Run Code Online (Sandbox Code Playgroud)
永远不会工作,因为在
将行放入模式空间之前删除了尾随换行符.要执行上述任务,请
改为使用以下脚本之一:
tr -d '\n' < file # use tr to delete newlines
sed ':a;N;$!ba;s/\n//g' file # GNU sed to delete newlines
sed 's/$/ foo/' file # add "foo" to end of each line
Run Code Online (Sandbox Code Playgroud)
由于除了GNU sed之外的sed版本对
模式缓冲区的大小有限制,因此Unix'tr'实用程序在这里是首选.
如果文件的最后一行包含换行符,GNU sed会
将该换行符添加到输出中但删除所有其他
换行符,而tr将删除所有换行符.
要匹配两行或更多行的块,有3种基本选择:
(1)使用'N'命令将Next行添加到模式空间;
(2)使用'H'命令至少两次将当前行追加
到Hold空间,然后
用x,g或G 从保留空间中检索行; 或(3)使用地址范围(见上文第3.3节)
来匹配两个指定地址之间的行.
选择(1)和(2)将\n放入模式空间,
可以根据需要对其进行寻址('s/ABC \nXYZ/alphabet/g').
使用"N"删除行块的一个示例显示在4.13节
("如何删除特定连续行的块?")中.
可以通过将delete命令更改为其他
内容来修改此示例,例如'p'(打印),'i'(插入),'c'(更改),'a'(追加)
或's'(替换) .
选择(3)不会将\n放入模式空间,但它确实
匹配连续行的块,因此您可能
甚至不需要\n来找到您要查找的内容.由于GNU sed
版本3.02.80现在支持这种语法:
sed '/start/,+4d' # to delete "start" plus the next 4 lines,
Run Code Online (Sandbox Code Playgroud)
除了传统的'/ from here /,/ to there/{...}'范围
地址之外,还可以完全避免使用\n.
Tho*_*hor 218
更短的awk替代方案:
awk 1 ORS=' '
Run Code Online (Sandbox Code Playgroud)
awk程序由条件代码块组成的规则构成,即:
condition { code-block }
Run Code Online (Sandbox Code Playgroud)
如果省略代码块,则使用默认值:{ print $0 }
.因此,它1
被解释为真实条件并且print $0
对每一行执行.
当awk
读取输入时,它会根据RS
(记录分隔符)的值将其拆分为记录,默认情况下是新行,因此awk
默认情况下会解析输入行.拆分还涉及RS
从输入记录中剥离.
现在,在打印记录时,ORS
(输出记录分隔符)会附加到其上,默认值也是换行符.因此,通过更改ORS
为空格,所有换行都将更改为空格.
JJo*_*oao 133
gnu sed有一个-z
空分隔记录(行)选项.你可以打电话:
sed -z 's/\n/ /g'
Run Code Online (Sandbox Code Playgroud)
ire*_*ses 84
在Perl的版本的作品您预期的方式.
perl -i -p -e 's/\n//' file
Run Code Online (Sandbox Code Playgroud)
正如评论中指出的那样,值得注意的是,这种编辑已经到位.-i.bak
如果您的正则表达式没有您想象的那么聪明,它会在替换之前为您提供原始文件的备份.
com*_*ike 44
谁需要sed
?这是bash
方式:
cat test.txt | while read line; do echo -n "$line "; done
Run Code Online (Sandbox Code Playgroud)
Pau*_*ce. 26
为了使用awk替换所有换行符,而不将整个文件读入内存:
awk '{printf "%s ", $0}' inputfile
Run Code Online (Sandbox Code Playgroud)
如果你想要一个最终换行符:
awk '{printf "%s ", $0} END {printf "\n"}' inputfile
Run Code Online (Sandbox Code Playgroud)
您可以使用空格以外的字符:
awk '{printf "%s|", $0} END {printf "\n"}' inputfile
Run Code Online (Sandbox Code Playgroud)
bre*_*ner 21
三件事.
tr
cat
绝对不需要(或等).(GNU)sed
和(GNU)awk
合并后,可以完成99.9%的文本处理.
stream!=基于行.ed
是一个基于行的编辑器.sed
不是.有关差异的更多信息,请参阅sed讲座.大多数人混淆sed
是基于行的,因为默认情况下,它在SIMPLE匹配的模式匹配中并不是非常贪婪 - 例如,在进行模式搜索并替换一个或两个字符时,默认情况下它只替换第一个匹配它找到(除非全局命令另有指定).如果它是基于行的而不是基于STREAM的,那么甚至不会有全局命令,因为它一次只评估行.试试跑步ed
; 你会发现差异.ed
如果你想迭代特定的行(例如在for循环中),但是大多数时候你只想要它,这非常有用sed
.
话虽如此,
sed -e '{:q;N;s/\n/ /g;t q}' file
Run Code Online (Sandbox Code Playgroud)
在GNU sed
版本4.2.1中工作得很好.上面的命令将用空格替换所有换行符.输入它很难看并且有点麻烦,但它工作得很好.这{}
可以省略,因为它们仅出于理智的原因而被包括在内.
小智 21
tr '\n' ' '
Run Code Online (Sandbox Code Playgroud)
是命令.
简单易用.
小智 17
cat file | xargs
Run Code Online (Sandbox Code Playgroud)
为了完整起见
Jua*_*uan 12
答案是:一个标签......
...在命令行上的freebsd 7.2中不起作用:
( echo foo ; echo bar ) | sed ':a;N;$!ba;s/\n/ /g' sed: 1: ":a;N;$!ba;s/\n/ /g": unused label 'a;N;$!ba;s/\n/ /g' foo bar
但是如果你把sed脚本放在一个文件中或使用-e来"构建"sed脚本...
> (echo foo; echo bar) | sed -e :a -e N -e '$!ba' -e 's/\n/ /g' foo bar
要么 ...
> cat > x.sed << eof
:a
N
$!ba
s/\n/ /g
eof
> (echo foo; echo bar) | sed -f x.sed
foo bar
Run Code Online (Sandbox Code Playgroud)
也许OS X中的sed是相似的.
Ita*_*chi 12
为什么我没有找到一个简单的解决方案awk
?
awk '{printf $0}' file
Run Code Online (Sandbox Code Playgroud)
printf
将打印没有换行符的每一行,如果你想用空格或其他分隔原始行:
awk '{printf $0 " "}' file
Run Code Online (Sandbox Code Playgroud)
Coo*_*J86 11
我有这个问题.问题在于我需要解决方案来处理BSD(Mac OS X)和GNU(Linux和Cygwin)sed
以及tr
:
$ echo 'foo
bar
baz
foo2
bar2
baz2' \
| tr '\n' '\000' \
| sed 's:\x00\x00.*:\n:g' \
| tr '\000' '\n'
Run Code Online (Sandbox Code Playgroud)
输出:
foo
bar
baz
Run Code Online (Sandbox Code Playgroud)
(有尾随换行符)
它适用于Linux,OS X和BSD - 即使没有UTF-8支持或蹩脚的终端.
用于tr
将换行符与另一个字符交换.
NULL
(\000
或\x00
)很好,因为它不需要UTF-8支持,也不太可能使用它.
使用sed
匹配NULL
使用tr
如果你需要他们交换回额外的新行
Vyt*_*nis 11
你可以使用xargs:
seq 10 | xargs
Run Code Online (Sandbox Code Playgroud)
要么
seq 10 | xargs echo -n
Run Code Online (Sandbox Code Playgroud)
我不是专家,但我想sed
你首先需要将下一行附加到模式空间中,bij使用" N
".从sed&awk一书中的"高级sed命令"中的"多行模式空间"一节(Dale Dougherty和Arnold Robbins; O'Reilly 1997; 预览中的第107页):
多行Next(N)命令通过读取新的输入行并将其附加到模式空间的内容来创建多行模式空间.模式空间的原始内容和新输入行由换行符分隔.嵌入的换行符可以通过转义序列"\n"以模式匹配.在多行模式空间中,元字符"^"匹配模式空间的第一个字符,而不是任何嵌入的换行符后面的字符.类似地,"$"仅匹配模式空间中的最终换行符,而不匹配任何嵌入换行符.执行Next命令后,控制权将传递给脚本中的后续命令.
来自man sed
:
[2addr] n的
将下一行输入附加到模式空间,使用嵌入的换行符将附加材料与原始内容分开.请注意,当前行号会发生变化.
我用它来搜索(多个)格式错误的日志文件,其中搜索字符串可能在"孤立的"下一行中找到.
小智 7
我使用混合方法绕过换行符,使用tr替换带有制表符的换行符,然后用我想要的任何内容替换制表符.在这种情况下,"
"因为我正在尝试生成HTML中断.
echo -e "a\nb\nc\n" |tr '\n' '\t' | sed 's/\t/ <br> /g'`
Run Code Online (Sandbox Code Playgroud)
小智 6
为响应上面的"tr"解决方案,在Windows上(可能使用的是Gnuwin32版本的tr),建议的解决方案:
tr '\n' ' ' < input
Run Code Online (Sandbox Code Playgroud)
我没有为我工作,它出错或实际上由于某种原因取代了\nw /''.
使用tr的另一个功能,"删除"选项-d确实有效:
tr -d '\n' < input
Run Code Online (Sandbox Code Playgroud)
或'\ r \n'而不是'\n'
小智 5
在某些情况下,您可以更改RS
为其他字符串或字符.这样,\n可用于sub/gsub:
$ gawk 'BEGIN {RS="dn" } {gsub("\n"," ") ;print $0 }' file
Run Code Online (Sandbox Code Playgroud)
shell脚本的强大之处在于,如果您不知道如何以某种方式执行此操作,则可以通过其他方式执行此操作.很多时候,你需要考虑更多的事情,而不是在一个简单的问题上做出复杂的解决方案.
至于那呆子的东西很慢......和读取文件到内存中,我不知道这一点,但对我来说似乎呆子当时有一条线工作,是非常非常快(不是快一些其他的,但写作和测试的时间也很重要).
我处理MB甚至GB的数据,我发现的唯一限制是行大小.
POSIX sed 需要根据 POSIX文本文件 和 POSIX行 定义输入,因此不允许使用NULL字节和太长行,并且每行必须以换行符结尾(包括最后一行).这使得难以使用sed处理任意输入数据.
以下解决方案避免使用sed,而是将输入字节转换为八进制代码,然后再转换为字节,但截取八进制代码012(换行符)并输出替换字符串代替它.据我所知,该解决方案符合POSIX标准,因此它应该可以在各种平台上运行.
od -A n -t o1 -v | tr ' \t' '\n\n' | grep . |
while read x; do [ "0$x" -eq 012 ] && printf '<br>\n' || printf "\\$x"; done
Run Code Online (Sandbox Code Playgroud)
POSIX参考文档: sh, shell命令语言, od, tr, grep, read, [, printf.
这两个read
,[
和printf
有内置插件至少在bash的,但很可能不是由POSIX保证,所以在一些平台上它可能是每一个输入字节将启动一个或多个新的进程,这将慢下来.即使在bash中,此解决方案仅达到约50 kB/s,因此它不适合大文件.
在Ubuntu(bash,dash和busybox),FreeBSD和OpenBSD上测试过.
你也可以使用这个方法:
sed 'x;G;1!h;s/\n/ /g;$!d'
Run Code Online (Sandbox Code Playgroud)
x - which is used to exchange the data from both space (pattern and hold).
G - which is used to append the data from hold space to pattern space.
h - which is used to copy the pattern space to hold space.
1!h - During first line won't copy pattern space to hold space due to \n is
available in pattern space.
$!d - Clear the pattern space every time before getting the next line until the
the last line.
Run Code Online (Sandbox Code Playgroud)
当第一行从输入中获取时,进行交换,因此1
进入保持空间并\n
进入模式空间,将保持空间附加到模式空间,并执行替换并删除模式空间。
在第二行期间,进行交换,2
进入保持空间并1
进入模式空间,G
将保持空间附加到模式空间中,h
将模式复制到其中,进行替换并删除。这个操作一直持续到达到 EOF 并打印出准确的结果。
使用允许查找和替换 \n
sed -ie -z 's/Marker\n/# Marker Comment\nMarker\n/g' myfile.txt
Run Code Online (Sandbox Code Playgroud)
标记
成为
# 标记注释
标记
If you are unfortunate enough to have to deal with windows line endings you need to remove the \r
and the \n
tr '[\r\n]' ' ' < $input > $output
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1570839 次 |
最近记录: |