如何递归地将 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
谁能帮我把文件的 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