按列拆分文件

3
我知道cut命令可以从文件中剪切一列(或多列),但是我需要用什么方法将一个文件分割成多个文件,使每个文件的名称为该列中的第一行,并且生成的文件数与原始文件中的列数相同? 示例(编辑) 列以TAB分隔,长度可能不同。我希望第一个文件实际上具有行的名称。
Probe File1.txt File2.txt File3.txt
"1007_s_at" 7.84390328616472 7.60792223630275 7.77487266222512
...

还有一件事就是原始文件非常巨大,因此我希望有一种解决方案可以在一次运行中将其拆分。不能反复调用切割命令。


所有列的宽度都相同吗?这也应该自动检测吗? - A.H.
你能否发布一份输入数据的样本? - MattH
1个回答

6

可以用一行awk命令完成:

$ cat test.tsv
field1  field2  field3  field4
asdf    asdf    asdf    asdf
lkjlkj  lkjlkj  lkjlkj  lkjlkj
feh     feh     feh     bmeh

$ awk -F'\t' 'NR==1 {  for(i=1;i<=NF;i++) { names[i] = $i }; next } { for(i=1;i<=NF;i++) print $i >> names[i] }' test.tsv

$ ls
field1  field2  field3  field4  test.tsv

$ cat field4
asdf
lkjlkj
bmeh

经Glenn Jackman提醒,将制表符分隔符包含在内进行编辑


补充

从字段中删除双引号:

awk -F'\t' 'NR==1 {  for(i=1;i<=NF;i++) { names[i] = $i }; next } { for(i=1;i<=NF;i++) {gsub(/"/,"",$i); print $i >> names[i] }}' example.tsv

附加说明

仅从字段开头或结尾删除双引号:

awk -F'\t' 'NR==1 {  for(i=1;i<=NF;i++) { names[i] = $i }; next } { for(i=1;i<=NF;i++) {gsub(/^"|"$/,"",$i); print $i >> names[i] }}' example.tsv

由于规范声明文件是以制表符分隔的,建议使用 awk -F '\t' - glenn jackman
抱歉,您能添加一段代码来删除值中的双引号吗?我不擅长 AWK。 - Sergej Andrejev
跟踪您的示例文件操作(加上一些额外的行),只显示每个字段一个打开系统调用和缓冲写入。如果您有很多字段,可能会超过它将缓存的文件描述符数量。 - MattH
我有5372个字段和22000行。速度很慢(目前只完成了约5%)。我想要更快的东西。如果我使用C ++实现,你认为Linux是否允许我拥有5372个文件句柄? - Sergej Andrejev
是的,那是我现在所做的。我把它留在PBS系统上。我会在星期一检查它。 - Sergej Andrejev
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接