如何递归地将 n 行合并为一行

How to bring n rows into a single line recursively

谁能帮我把文件的 n 行合并成一行。

这是我要实现的示例:

$ cat samplefile.txt
aaa AAA  XX
bbb BBB  AA
ccc CCC AA
ddd DDD 12
eee EEE 3
fff FFF
ggg GGG 3 
hhh HHH4 55
iii III 33
jjj JJJ

$ cat desiredfile
aaa AAA XX bbb BBB AA ccc CCC AA ddd DDD 12 eee  EEE 3
fff FFF ggg GGG 3 hhh HHH4 55 iii III 33 jjj JJJ

这里 n=5 ,我需要每 5 行作为分隔符。不确定如何实现这一点。请指教。

这会在每行之间打印 spaces,但在打印换行符时每五行除外:

$ awk '{printf "%s%s",[=10=],(NR%5?OFS:ORS)} END{print""}' samplefile.txt 
aaa AAA  XX bbb BBB  AA ccc CCC AA ddd DDD 12 eee EEE 3
fff FFF ggg GGG 3  hhh HHH4 55 iii III 33 jjj JJJ

工作原理

awk 隐式循环遍历文件中的所有行

  • printf "%s%s",[=12=],(NR%5?OFS:ORS)

    这会打印两个字符串的格式。第一个字符串是 [=13=] ,这是我们刚刚读取的行。第二个字符串是三元语句的结果:

    `NR%5?OFS:ORS`
    

    NR 是到目前为止读取的行数。 NR%5 是到目前为止读取的行数模 5。如果 NR%5 非零,则此语句 returns 输出字段分隔符 OFS。默认情况下 OFS 是 space。如果为零,则语句returns输出记录分隔符,ORS。默认情况下,ORS 是换行符。因此,每第五行,这个三元语句 returns 一个换行符。在其他方面,它 returns a space.

  • END{print""}

    到达文件末尾后,将打印换行符。这确保我们在输出末尾至少有一个换行符。

awk -vl=5 'ORS=++c%l?" ":"\n"' file
aaa AAA  XX bbb BBB  AA ccc CCC AA ddd DDD 12 eee EEE 3
fff FFF ggg GGG 3  hhh HHH4 55 iii III 33 jjj JJJ

解释:

++c 自动计数

++c % l == 0 <=> 5 % 5 == 0 ===> ORS="\n"

这可能适合您 (GNU sed):

sed ':a;N;s/[^\n]*/&/5;Ta;y/\n/ /' file

继续向模式 space 添加行,直到模式匹配所需的匹配数(在本例中为 5),然后用 space.

替换每个换行符

另一种使用粘贴的方法是:

paste -sd'    \n' file

其中选项分隔符 (-d) 包含四个 space 和一个换行符 (\n)。

或使其程序化:

paste -sd"$(printf '%*s\n' 4)" file

假设第一行从零开始。

您可以使用 xargs 并告诉它一次读取 5 行。它的默认操作是回显它的参数,这就是你想要的:

xargs -L5 < samplefile.txt

aaa AAA XX bbb BBB AA ccc CCC AA ddd DDD 12 eee EEE 3
fff FFF ggg GGG 3 hhh HHH4 55 iii III 33 jjj JJJ