【发布时间】:2022-02-07 18:06:19
【问题描述】:
我有一个包含数百万行和数千列的数据文件。我需要某些行和某些列的数据。我有一个包含我需要的行号的文本文件,以及另一个包含我需要的列标题的文本文件。我必须像这样对几百个数据文件进行子集化,所以我试图弄清楚如何快速完成它,而不会创建巨大的中间文件。
我在 bash 脚本方面不是很有经验。到目前为止,我最好的方法是使用 awk 提取必要的行来创建一个中间文件,并将结果通过管道传输到 cut 以便输出文件只包含必要的列:
COLS=($(zcat big_zipped_file.txt.gz | head -n 1 | tr '\t' '\n' | grep -nf column_headers.txt | sed 's/:.*$//'))
awk 'NR==FNR{a[$0];next} FNR in a' line_numbers.txt <(zcat big_zipped_file.txt.gz) |
cut -f 1$(printf ",%s" "${COLS[@]}") >> output_file
有没有一种方法可以更快,并且不会创建大型临时文件?
【问题讨论】:
-
考虑查看How to create a minimal, reproducible example?,然后回来更新问题;特别是包含行和列标题数据的示例文件,具有 5-10 行和列的输入文件(应该包括要保留的行和列以及要忽略的一些),代码生成的(错误)输出,和(正确的)预期输出
-
csvkit 包中的
csvcut通常可以方便地按名称提取列。 -
markp-fuso:感谢您的回复。该问题适用于任何具有行和列的大文件,因此我故意省略了示例文件,因为它们会造成不必要的混乱。也许我应该澄清一下我已经得到了正确的输出。问题是:有没有更有效的获取方式?
-
列文件和行文件是所有数据文件通用的吗?编号为
1的行对应什么:标题或标题后的第一行数据?
标签: linux bash performance memory subset