【问题标题】:splitting values based on values in a specific column根据特定列中的值拆分值
【发布时间】:2016-02-02 19:10:38
【问题描述】:

我有一个文件,我想将其拆分为多个文件,其中第一列的值为 uniq。例如,这是一个文件:

文件A.txt

1    Cat
1    Dog
1    Frog
2    Boy
2    Girl
3    Tree
3    Leaf
3    Branch
3    Trunk

我希望我的输出看起来像这样:

file1.txt

1    Cat
2    Boy
3    Tree

file2.txt

1    Dog
2    Girl
3    Leaf

file3.txt

1    Frog
3    Branch

file4.txt

3    Trunk

如果一个值不存在,我希望它被跳过。我试图寻找与我类似的情况,但我做不到。有谁知道如何做到这一点?

理论上,这个 awk 命令应该可以工作:awk '{print > "file" ++a[$1] ".txt"}' input。但是,我无法让它正常工作(很可能是因为我在 Mac 上工作)有人知道另一种方法吗?

【问题讨论】:

  • @EdMorton 这就是问题所在。谢谢!

标签: python bash awk


【解决方案1】:

输出重定向右侧未加括号的表达式是未定义的行为。试试awk '{print > ("file" ++a[$1] ".txt")}' input。

如果同时打开太多文件是个问题,那么请使用 GNU awk,但如果你不能:

$ ls
 fileA.txt

$ awk '{f="file" ++a[$1] ".txt"; print >> f; close(f)}' fileA.txt

$ ls
file1.txt  file2.txt  file3.txt  file4.txt  fileA.txt

$ cat file1.txt
1    Cat
2    Boy
3    Tree

【讨论】:

  • 我注意到,当我使用它时,我得到了一个错误。 awk: file18.txt makes too many open files input record number 19, file input.txt source line number 1你知道在我阅读我的实际文件时是否有办法关闭文件吗?也许awk '{print >> ("file" ++a[$1] ".txt")}' input?
  • @interstellar 在 AWK 中,> 和 >> 与 bash 等 shell 略有不同。每次执行该行时,print > 和 print >> 都会附加到文件中。不同之处在于第一次执行该行时会发生什么。第一次执行 print > 时,它会将文件截断为零,然后附加到它(以及随后的每次)。 print >> 将在第一次不截断的情况下追加。您希望 AWK 创建新的输出,而不是保留以前的任何垃圾,因此 > 适合 @EdMorton 的回答。
  • @interstellar 当然,只需调用 close()。如果您使用 GNU awk,您将不会遇到此问题,因为它在内部管理文件状态。我编辑了答案以显示如何添加 close()。
【解决方案2】:

这里有一个 Python 解决方案:

from collections import Counter
fd_dict = {}
ind_counter = Counter()

with open('fileA.txt') as inf:
    for line in inf:
        ind, _ = line.split()
        ind_counter[ind] += 1
        file_ind = ind_counter[ind]
        fd = (
            fd_dict[file_ind] if file_ind in fd_dict else
            fd_dict.setdefault(
                file_ind, 
                open('file{}.txt'.format(file_ind), 'w')))
        fd.write(line)

for fd in fd_dict.itervalues():
    fd.close()

【讨论】:

    猜你喜欢
    • 2023-03-14
    • 1970-01-01
    • 2021-01-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-24
    • 2021-01-17
    相关资源
    最近更新 更多