如何使用sed替换换行符(\n)?

hhh*_*hhh 1295 sed

如何\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)

  • sed在输入的"流"上工作,但它以换行符分隔的块来理解它.它是一个unix工具,这意味着它做得很好.一件事是"在文件行上工作".让它做其他事情会很难,而且冒险.故事的寓意是:选择合适的工具.你的很多问题似乎都采用了"我怎样才能让这个工具做一些从未打算过的事情?"的形式.这些问题很有意思,但如果他们在解决实际问题的过程中遇到问题,那么你可能做错了. (185认同)
  • Sed是基于行的,因此很难掌握换行符. (87认同)
  • tr很棒,但你只能用单个字符替换换行符.如果要使用字符串替换换行符,则需要使用其他工具 (68认同)
  • @Eddy - 我用tr替换了一个没有出现在文本中的字符的新行(我使用了反引号),然后sed用我想要使用的字符串替换反引号 (20认同)
  • `tr` 仅适用于一个字符串。您无法将所有新行替换为多个字符长的字符串。 (7认同)
  • @JBBrown`tr`是一种经常被忽视的宝石,用于建造管道. (5认同)
  • @elgalu - 这很可能是因为作为字符的颜色会干扰您的搜索/替换模式.在需要时,我使用以下别名来删除流中的颜色:`alias noc ='sed -r"s /\x1B\[([0-9] {1,2}(; [0-9] {1 ,2}))?[M | K] //克"'` (5认同)
  • 这个答案非常有助于我将一个(日志)文件的三个连续行组合成一个,通过以下过程:grep --after-context 3(pattern)(file)| tr'\n'''| sed -e's/ - /\n/g'. (4认同)
  • 作为旁注,` - delete`在FreeBSD上不起作用.仅使用`-d`可以提高答案的可移植性. (4认同)
  • 亚历山大:“流编辑器”是指基于行的吗?也许,这个名字令人困惑。 (3认同)
  • 这个问题的'tr'语法似乎非常简单,比sed更容易理解. (2认同)
  • 我的意思是使用sed做一些正则表达式替换它必须匹配包含换行符的字符串.这与OP问题相距甚远. (2认同)

Zso*_*kai 1434

在GNU中使用此解决方案sed:

sed ':a;N;$!ba;s/\n/ /g' file
Run Code Online (Sandbox Code Playgroud)

这将在循环中读取整个文件,然后用空格替换换行符.

说明:

  1. 通过创建标签:a.
  2. 将当前和下一行附加到模式空间via N.
  3. 如果我们在最后一行之前,则跳转到创建的标签$!ba($!意味着不要在最后一行执行,因为应该有一个最终换行符).
  4. 最后,替换用模式空间(即整个文件)上的空格替换每个换行符.

这是与BSD和OS X一起使用的跨平台兼容语法sed(根据@Benjie评论):

sed -e ':a' -e 'N' -e '$!ba' -e 's/\n/ /g' file
Run Code Online (Sandbox Code Playgroud)

如您所见,使用sed这个简单的问题是有问题的.有关更简单和适当的解决方案,请参阅此答案.

  • 您可以通过单独执行命令而不是用分号分隔来运行这个跨平台(即在Mac OS X上):`sed -e':'-e'N'-e'$!ba'-e' s/\n// g'` (105认同)
  • 为什么没有人评论这是一个愚蠢的混乱(不是答案本身,而是提出的答案是解决一个非常简单的问题的最佳解决方案).Sed看起来像一辆通常运行良好的汽车,但如果你想开车到附近的特定街道,唯一的办法就是用直升机抬起汽车. (69认同)
  • `:a`不是寄存器,它是分支标签.它是`b`命令*的目标,其工作方式类似于"goto".将其称为寄存器意味着您可以创建存储位置.只有两个"寄存器"; 一个称为"保留空间",您的脚本未使用,另一个称为"模式空间".`N`命令将换行符和输入文件的下一行附加到模式空间.[*你可以有多个标签和`b`命令.如果你有一个没有附加标签字符的`b`命令,它会跳转到脚本的末尾以读取下一行并再次循环. (50认同)
  • @Arjan和Masi:OS X使用BSD的`sed`而不是GNU`sed',因此两者之间可能存在一些微妙的(有些不那么微妙的)差异.如果您在OS X和*nix机器上工作,这将是一个持续的痛苦.我通常在OS X上安装GNU的`coreutils`和`findutils`,并忽略BSD版本. (45认同)
  • 来吧伙计们 - 261赞成一个疯狂的,难以理解的解决方案,不起作用???? sed是一个很好的工具,可以在一行上进行简单的替换,只需使用awk即可.好悲伤.... (11认同)
  • `回声“你好\n世界”| sed -e ':a' -e 'N' -e '$!ba' -e 's/\n/ /g'` 返回 "Hello World",但 `echo "Hello World" | sed -e ':a' -e 'N' -e '$!ba' -e 's/\n/ /g'` 为我返回一个空字符串。我使用的是 MacOS Big Sur。 (6认同)
  • 这也是'sed':a; {N; s/\n//}; ba'`:P (5认同)
  • 这是一个令人印象深刻的答案。我还觉得讽刺的是,Linux 工具应该“做好一件事”,而大多数 Linux 工具似乎能做很多事情,但效果很差 (5认同)
  • @EdMorton你是绝对正确的,我不会自己使用它(`tr`对于这个来说简单得多).不过,问题是如何用"sed"来做这件事,在过去的好时光里,我已经读过,理解并回答了这个问题.对我来说它是有效的(虽然我已经阅读了一些用于学习这个奇妙工具的文档,但我确实以某种方式理解了它). (3认同)
  • 好像没有去掉最后一个\n? (3认同)
  • 输入的最后一行不会被替换.例如`printf'1 \n2 \n3 \n'| sed':a; N; $!ba; s/\n// g'`将给出'1 2 3 \n`. (2认同)
  • @ZsoltBotykai看到我之前的评论,并且使用\n只能在某些操作系统上的某些seds中工作 - 在sed中指定换行符的可移植方式是反斜杠后跟一个文字换行符.只需阅读上面的评论 - 大约三分之一的人说这对他们不起作用,另外三分之一的人说他们不理解.你不应该像这样的东西使用sed. (2认同)
  • 为什么":a; N; $!ba; s/\n// g"工作而不只是"s/\n// g"? (2认同)
  • @trusktr看到这个答案:http://stackoverflow.com/a/7697604/11621有一个从官方sed FAQ复制的解释. (2认同)
  • @atti $!使整个encantation将所有行累积到模式缓冲区中,然后从该缓冲区进行大量替换并进行一次打印. (2认同)

hdo*_*rio 463

快速回答:

sed ':a;N;$!ba;s/\n/ /g' file
Run Code Online (Sandbox Code Playgroud)
  1. : 创建标签'a'
  2. N 将下一行附加到模式空间
  3. $! 如果不是最后一行,ba 分支(转到)标签'a'
  4. s 替换,/ \n/ 正则表达式为新行,// 由空格,/ g 全局匹配(尽可能多次)

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.

  • `tr`是个好主意,你的整体报道可以提供最优质的答案. (6认同)
  • 关于这个答案最好的部分是"长答案"解释了命令的工作原理和原因. (4认同)
  • +1 用于使用 ([标准实用程序](http://pubs.opengroup.org/onlinepubs/9699919799/utilities/paste.html)) `paste`... 以及所有其他! (2认同)
  • 这可能是我在stackexchange上阅读的数千个答案中最有帮助的.我需要跨行匹配多个字符.没有先前的sed示例涵盖多行和tr无法处理多个字符匹配.Perl看起来不错,但是没有像我期望的那样工作.如果可以的话,我会多次投票给这个答案. (2认同)

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为空格,所有换行都将更改为空格.

  • 如果它更有意义,这可以有效地写成:`awk'BEGIN {ORS =""} {print $ 0} END {print"\n"}'file.txt`(添加结尾换行只是为了说明开始/结束); "1"评估为"true"(处理行)和"print"(打印行).条件也可以添加到此表达式中,例如,仅处理匹配模式的行:`awk'BEGIN {ORS =""}/pattern/{print $ 0} END {print"\n"}'` (8认同)
  • 我非常喜欢这个简单的解决方案,它比其他解决方案更具可读性 (5认同)
  • 你可以做得更简单:`code` awk 'ORS=" "' file.txt `code` (2认同)
  • @Jonah:这是设置变量的另一种方法,请参见例如[GNU awk 手册](https://www.gnu.org/software/gawk/manual/gawk.html#Other-Arguments) (2认同)

JJo*_*oao 133

gnu sed有一个-z空分隔记录(行)选项.你可以打电话:

sed -z 's/\n/ /g'
Run Code Online (Sandbox Code Playgroud)

  • 如果没有空值,这不会加载整个输入吗?在这种情况下,处理一个数千兆字节的文件可能会崩溃. (6认同)
  • 这是**最好的**答案.其他表达式太扭曲而无法记住.@JJoao您可以将它与`-u, - unbuffered`一起使用.`man` mage说:"从输入文件加载最少量的数据并更频繁地刷新输出缓冲区". (6认同)
  • 即使输入确实包含空值,它们也将被保留(作为记录分隔符). (4认同)
  • @Ruslan,是的,它加载了整个输入.对于千兆字节的文件,这个解决方案不是一个好主意. (3认同)
  • 很少使用的“y”命令也可以完成这项工作“sed -z 'y/\n/ /' file”。 (2认同)

ire*_*ses 84

Perl的版本的作品您预期的方式.

perl -i -p -e 's/\n//' file
Run Code Online (Sandbox Code Playgroud)

正如评论中指出的那样,值得注意的是,这种编辑已经到位.-i.bak如果您的正则表达式没有您想象的那么聪明,它会在替换之前为您提供原始文件的备份.

  • 请至少提一下,没有后缀的`-i`会使*没有备份*.`-i.bak`保护你免受一个简单,丑陋的错误(比如,忘记键入`-p`并将文件归零). (22认同)
  • @Telemachus:这是一个公平的观点,但无论如何都可以争论.我没有提到它的主要原因是OP问题中的sed示例没有进行备份,因此这里似乎是多余的.另一个原因是我从未真正使用过备份功能(实际上我发现自动备份很烦人),所以我总是忘记它在那里.第三个原因是它让我的命令行变长了四个字符.无论好坏(可能更糟),我都是一个强迫性的极简主义者; 我只是喜欢简洁.我意识到你不同意.我将尽力记住将来警告备份. (5认同)
  • @Ire_and_curses:实际上,你只是因为无视我而做出了一个非常好的论据.也就是说,你有理由做出选择,无论我是否同意这些选择,我当然都会尊重这一点.我不确定为什么,但我最近对这个特殊的东西一直在撕裂(Perl中的`-i`标志没有后缀).我相信我很快就能找到别的东西来讨论.:) (5认同)

com*_*ike 44

谁需要sed?这是bash方式:

cat test.txt |  while read line; do echo -n "$line "; done
Run Code Online (Sandbox Code Playgroud)

  • 甚至没有使用`cat`:`读取线; 做echo -n"$ line"; 完成<test.txt`.如果子shell是个问题,可能会有用. (10认同)
  • @Tony因为反引号被弃用而且cat是多余的;-)使用:echo $(<days.txt) (9认同)
  • `echo $(<file)`将所有**空格压缩到一个空格,而不仅仅是换行:这超出了OP所要求的范围. (5认同)
  • Upvote,我通常使用最佳答案,但是当通过它来管道/ dev/urandom时,sed将不会打印直到EOF,而^ C不是EOF.每次看到换行符时都会打印此解决方案.正是我需要的!谢谢! (2认同)

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)

  • `END{ print ""}` 是尾随换行符的更短替代方案。 (2认同)

bre*_*ner 21

三件事.

  1. trcat绝对不需要(或等).(GNU)sed和(GNU)awk合并后,可以完成99.9%的文本处理.

  2. stream!=基于行.ed是一个基于行的编辑器.sed不是.有关差异的更多信息,请参阅sed讲座.大多数人混淆sed是基于行的,因为默认情况下,它在SIMPLE匹配的模式匹配中并不是非常贪婪 - 例如,在进行模式搜索并替换一个或两个字符时,默认情况下它只替换第一个匹配它找到(除非全局命令另有指定).如果它是基于行的而不是基于STREAM的,那么甚至不会有全局命令,因为它一次只评估行.试试跑步ed; 你会发现差异.ed如果你想迭代特定的行(例如在for循环中),但是大多数时候你只想要它,这非常有用sed.

  3. 话虽如此,

    sed -e '{:q;N;s/\n/ /g;t q}' file
    
    Run Code Online (Sandbox Code Playgroud)

    在GNU sed版本4.2.1中工作得很好.上面的命令将用空格替换所有换行符.输入它很难看并且有点麻烦,但它工作得很好.这{}可以省略,因为它们仅出于理智的原因而被包括在内.

  • 什么是'one`?我不知道这个命令! (3认同)
  • 这比大输入时接受的答案慢了近 800 倍。这是由于在越来越大的输入上运行替代品。 (3认同)
  • 作为一个只知道"sed"来做基本事情的人,我不得不说这不仅仅是你能用'sed`做什么,而是知道发生了什么是多么容易.我在使用`sed`时非常困难,所以当我可以使用它时,我更喜欢更简单的命令. (2认同)

小智 21

tr '\n' ' ' 
Run Code Online (Sandbox Code Playgroud)

是命令.

简单易用.

  • 或者只是`tr -d'\n'`如果你不想添加空格 (13认同)

小智 17

cat file | xargs
Run Code Online (Sandbox Code Playgroud)

为了完整起见

  • 我对 bash 有点生疏,但是这里不需要“cat”吗?“xargs &lt; file”会更好吗? (3认同)

Jua*_*uan 12

答案是:一个标签......

如何使用sed替换换行符(\n)?

...在命令行上的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支持或蹩脚的终端.

  1. 用于tr将换行符与另一个字符交换.

    NULL(\000\x00)很好,因为它不需要UTF-8支持,也不太可能使用它.

  2. 使用sed匹配NULL

  3. 使用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)


Arj*_*jan 9

我不是专家,但我想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'

  • 在Windows上,您可能需要使用`tr"\n"""<input`.Windows shell(cmd.exe)不会将撇号视为引用字符. (3认同)

小智 5

在某些情况下,您可以更改RS为其他字符串或字符.这样,\n可用于sub/gsub:

$ gawk 'BEGIN {RS="dn" } {gsub("\n"," ") ;print $0 }' file
Run Code Online (Sandbox Code Playgroud)

shell脚本的强大之处在于,如果您不知道如何以某种方式执行此操作,则可以通过其他方式执行此操作.很多时候,你需要考虑更多的事情,而不是在一个简单的问题上做出复杂的解决方案.

至于那呆子的东西很慢......和读取文件到内存中,我不知道这一点,但对我来说似乎呆子当时有一条线工作,是非常非常快(不是快一些其他的,但写作和测试的时间也很重要).

我处理MB甚至GB的数据,我发现的唯一限制是行大小.

  • 无用的`猫`. (4认同)

Håk*_*and 5

防弹解决方案.二进制数据安全和POSIX兼容,但速度慢.

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上测试过.


Kal*_*dhi 5

你也可以使用这个方法:

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 并打印出准确的结果。


Pro*_*imo 5

使用允许查找和替换 \n

sed -ie -z 's/Marker\n/# Marker Comment\nMarker\n/g' myfile.txt
Run Code Online (Sandbox Code Playgroud)

标记

成为

# 标记注释

标记


Ste*_*rCS 5

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)