将记录堆叠到列中

将记录堆叠到列中

有一个这样的文件:

1
2
3
     # always a double newline
a
b
c     # each subgroup has the same number of rows

9
10

y
z
...

基本上是第 1 列,后跟双换行符,然后是第二列,双换行符,然后回到第 1 列

不要对值的性质(它们可以是任何东西)或“列”的数量(可以是 2 或 3,尽管提前知道)做出假设

希望得到这样的输出:

1,a
2,b
3,c
9,y
10,z
...

什么是适合这项工作的工具?

答案1

awk使用和 的另一个解决方案bash

paste -d, <(awk -v RS='\n\n' 'NR%2' file) <(awk -v RS='\n\n' '!(NR%2)' file)

这只考虑空行作为分隔符,非空行可以是任何内容。

答案2

使用示例输入文件的快速解决方案(我将您的输入数据复制/粘贴到名为 c2.txt 的本地文件)。它并未在所有条件下测试可能出现的故障,但您可以尝试一下,看看结果是否令您满意。

$ paste -d"," <(grep -E '[0-9]' c2.txt) <(grep -E '[a-z]' c2.txt)
1,a
2,b
3,c
9,y
10,z

实际上我 grep 同一个文件两次。一个用于字符串,一个用于将它们粘贴在一起。

答案3

在段落模式下使用 awk 怎么样?将每个奇数记录拆分为索引数组,然后使用以下偶数记录的索引循环遍历它:

awk -vRS= -F'\n' '
   NR%2 {split($0,a); next} {for (i=1;i<=NF;i++) print a[i],$i}
' OFS=, file
1,a
2,b
3,c
9,y
10,z

使用换行符字段分隔符可以安全地进行更一般的输入,例如给定的file2

foo
bar
baz bar

a
b
c

9
10

hello world
z

然后

awk -vRS= -F'\n' '
  NR%2 {split($0,a); next} {for (i=1;i<=NF;i++) print a[i],$i}
' OFS=, file2
foo,a
bar,b
baz bar,c
9,hello world
10,z

答案4

Python 2 脚本

由于OP要求输入值可以是任何值,并且只能使用双换行符作为指导评论,这是脚本的替代版本(原始版本可以在这个答案的编辑历史中找到),使用steeldriver的输入文件进行测试:

#!/usr/bin/env python
from __future__ import print_function
import sys
columns = []
counter = 0

def print_columns(cols):
    half = len(cols)/2
    print("\n".join([ x+","+y for x,y in  zip(cols[0:half],cols[half:]) ]))

with open(sys.argv[1]) as fd:
    for line in fd:
        if line.strip() == '':
            counter+=1
            continue
        if counter >0 and counter%4 == 0: 
            print_columns(columns)
            columns = []
            counter = 0
        columns.append(line.strip())
print_columns(columns)

测试运行:

$ cat input.txt                                                                                                          
foo
bar
baz bar


a
b
c


9
10


hello world
z

$ ./columnate_file.py input.txt                                                                                          
foo,a
bar,b
baz bar,c
9,hello world
10,z

相关内容