每隔 N 行删除换行符

jom*_*web 17 text-processing

处理文本,我需要每两行删除换行符。

示例文本:

this is line one
and this is line two
the third and the
fourth must be pasted too
Run Code Online (Sandbox Code Playgroud)

期望的输出:

this is line one and this is line two
the third and the fourth must be pasted too
Run Code Online (Sandbox Code Playgroud)

我尝试了一个while循环,但是 while 循环是不好的做法。是否可以使用tr或任何其他命令来完成?

Sté*_*las 24

paste(也是一个标准的 POSIX 简单实用程序,如tr)是您的工具。

假设您希望将这些换行符替换为空格,而不是像示例中那样将其删除

paste -d ' ' - - < file
Run Code Online (Sandbox Code Playgroud)

或者:

paste -sd ' \n' file
Run Code Online (Sandbox Code Playgroud)

如果您确实希望删除它们,请替换' ''\0'

要替换 3 个中的 2 个:

paste -sd '  \n' file
Run Code Online (Sandbox Code Playgroud)

3 个中的 1 个,从第二个开始:

paste -sd '\n \n' file
Run Code Online (Sandbox Code Playgroud)

等等。

另一个好处paste是它不会留下未终止的行。例如,如果您删除文件中的每个换行符(如使用tr -d '\n' < filetr '\n' ' ' < file),则最终没有任何行,因为行需要以换行符终止。因此,通常最好使用它来paste代替(如 inpaste -sd '\0' filepaste -sd ' ' file),这将添加具有有效文本所需的尾随换行符。


Cos*_*tas 11

使用现代GNU sed

sed -rz 's/\n([^\n]*\n)/ \1/g' sample.text
Run Code Online (Sandbox Code Playgroud)

awk

awk '{getline line2;print $0, line2}' sample.text
Run Code Online (Sandbox Code Playgroud)

  • 这种 `sed` 方法意味着将整个文件放入内存中(前提是它不包含 NUL 字节)并进行一些昂贵的正则表达式替换。我看不出比标准的 `sed 'N;s/\n/ /'` 方法有什么好处。 (3认同)

SHW*_*SHW 6

sed为此使用如下所示:

SHW@SHW:/tmp $ cat a
this is line one
and this is line two
the third and the
fourth must be pasted too

SHW@SHW:/tmp $ sed 'N;s/\n/ /' a -i

SHW@SHW:/tmp $ cat a
this is line one and this is line two
the third and the fourth must be pasted too
Run Code Online (Sandbox Code Playgroud)


max*_*zig 5

另一种方法是使用xargs

$ < txt xargs -d '\n' -n 2 echo
this is line one and this is line two
the third and the fourth must be pasted too
Run Code Online (Sandbox Code Playgroud)

在哪里

$ cat txt
this is line one
and this is line two
the third and the
fourth must be pasted too
Run Code Online (Sandbox Code Playgroud)

虽然,这个解决方案相当过分,因为echo每行都执行一个进程......因此,除了玩具示例之外,应该首选基于 awk/sed 或类似的解决方案。


DJM*_*hem 5

这在vim中实际上非常简单。要加入每一行,请使用该J命令,然后使用该%norm命令将其同时应用于每一行。例如

:%norm J<CR>
Run Code Online (Sandbox Code Playgroud)

(以防万一你不熟悉vim,<CR>只是意味着进入)

This even works to join an arbitrary number of lines. For example, to join every ten lines would be

:%norm 9J<CR>
Run Code Online (Sandbox Code Playgroud)

If you are uncomfortable with vim, and you would prefer to use it as a command line tool, rather than an interactive text editor, you could do:

vim myfile -c '%norm J' -c 'wq'
Run Code Online (Sandbox Code Playgroud)