sed 和换行符有问题吗?
我有一个包含以下内容的文件 test.txt
aaaaa
bbbbb
ccccc
ddddd
Run Code Online (Sandbox Code Playgroud)
以下不起作用:
sed -r -i 's/\n/,/g' test.txt
我知道我可以使用tr它,但我的问题是为什么 sed 似乎不可能。
如果这是逐行处理文件的副作用,我会对为什么会发生这种情况感兴趣。我认为grep删除新行。sed 也一样吗?
Ant*_*hon 65
使用 GNUsed并提供POSIXLY_CORRECT不在环境中(用于单行输入):
sed -i ':a;N;$!ba;s/\n/,/g' test.txt
Run Code Online (Sandbox Code Playgroud)
:aN$!ba($!意味着不要在最后一行执行此操作(因为应该有一个最后的换行符))。Hie*_*nga 55
这适用于 GNU sed:
sed -z 's/\n/,/g'
Run Code Online (Sandbox Code Playgroud)
-z 自 4.2.2 起包含在内
注意。-z将分隔符更改为空字符 ( \0)。如果您的输入不包含任何空字符,则整个输入将被视为一行。这可能有其局限性。
为避免替换最后一行的换行符,您可以将其改回:
sed -z 's/\n/,/g;s/,$/\n/'
Run Code Online (Sandbox Code Playgroud)
(这又是 GNUsed语法,但这并不重要,因为整个事情只是 GNU)
mik*_*erv 11
sed总是\n在填充模式空间之前删除尾部的ewline,然后在写出其脚本的结果之前附加一个。\n可以通过各种方式在模式空间中使用ewline - 但如果它不是编辑的结果,则永远不会。这很重要 -的模式空间中的\newlinessed始终反映更改,并且永远不会出现在输入流中。\newlines 是sedder 可以依靠未知输入的唯一分隔符。
如果你想\n用逗号替换所有的ewlines 并且你的文件不是很大,那么你可以这样做:
sed 'H;1h;$!d;x;y/\n/,/'
Run Code Online (Sandbox Code Playgroud)
这会将每个输入行附加到h旧空间 - 除了第一个,它会覆盖h旧空间 - 跟随一个\newline 字符。然后它从输出中d删除每一行而不是$!最后一行。在最后一行Hold 和 pattern 空格被x更改,所有\newline 字符都被y///转换为逗号。
对于大文件,这种事情必然会导致问题 -sed线边界上的缓冲区,很容易被此类操作溢出。
小智 9
来自 Oracle 的网站:
sed 实用程序通过将文件一行一行地顺序读入内存来工作。然后,它执行为该行指定的所有操作,并将该行放回内存中以将所请求的更改转储到终端。在对这一行执行完所有操作后,它会读取文件的下一行并重复该过程,直到完成该文件。
基本上这意味着因为 sed 正在逐行读取换行符不匹配。
/sf/ask/87639961/的解决方案是:
sed ':a;N;$!ba;s/\n/,/g'
Run Code Online (Sandbox Code Playgroud)
或者,在便携式版本中(;在跳转标记标签后不连接)
sed -e ':a' -e 'N;$!ba' -e 's/\n/,/g'
Run Code Online (Sandbox Code Playgroud)
该页面上提供了有关其工作原理的说明。
小智 5
你的帖子实际上有两个问题:
sed 可以替换新行字符吗?
是的。绝对没错。任何 sed 都可以:
s/\n/,/g
Run Code Online (Sandbox Code Playgroud)
或者
y/\n/,/
Run Code Online (Sandbox Code Playgroud)
这会将任何换行符(进入模式空间)转换为逗号。
sed 和换行符有问题吗?
是的,sed 中的换行符有几个问题:
所有上述几点使得将换行符“转换”为任何内容都变得困难。
而且,如果换行符被另一个文本字符替换,那么 sed必须在内存中包含整个文本文件(无论使用什么进程到达那里)。
在 sed 中捕获内存中整个文件的几个解决方案是:
sed 'H;1h;$!d;x;y/\n/,/' file # most seds. [1]
sed ':a;N;$!ba;s/\n/,/g' file # GNU sed.
sed -z 's/\n/,/g;s/,$/\n/' file # GNU sed.
Run Code Online (Sandbox Code Playgroud)
一些不占用太多内存的快速解决方案是:
tr '\n' ',' file ; echo
awk '{printf("%s%s",NR==1?"":",",$0)}END{print ""}' file
Run Code Online (Sandbox Code Playgroud)
1来自 sed 解决方案:对于每一行,H 将行添加到保留空间(除了第一行完全替换保留空间(避免前导换行符)),然后擦除模式空间$!d(除了最后一行) 。在未被删除的最后一行上,其余命令将被执行。首先,获取保留空间中捕获的所有行x,然后用逗号替换所有换行符y/\n/,/。
| 归档时间: |
|
| 查看次数: |
216985 次 |
| 最近记录: |