从大型数据文件中提取/复制列的范围

从大型数据文件中提取/复制列的范围

我试图通过提取列并将其粘贴到新文件中来从一个大文件中准备数据文件。

给定数据的列数非常大。我想通过分割数据来准备多个数据文件。
我正在尝试下面的脚本,但它不起作用。我预计该错误是由于指定要复制的列范围造成的。

#!/bin/bash

paste <(awk '{print $1,$2,$3,...$19,$20}' Precipitation.csv ) > aaaaa1
paste <(awk '{print $21,$22,$23,...$39,$40}' Precipitation.csv ) > aaaaa2 
paste <(awk '{print $41,$42,$43,...$99,$100}' Precipitation.csv ) > aaaaa3 

您能帮我改正代码吗?

答案1

这看起来像是一个案例cut会比以下做得更好awk

cut -d , -f1-20 Precipitation.csv > aaa1
cut -d , -f21-40 Precipitation.csv > aaa2
cut -d , -f41-100 Precipitation.csv > aaa3

-d ,指定分隔符(逗号,因为输入称为 CSV,但您可以更改它)。通过包含-f N-M挑选出要出现在输出中的字段。如果任何字段中嵌入了逗号,它就会被破坏——在这种情况下,您可能需要一个真正的 CSV 解析器,尽管如果确实不可能的话,也可以将某些东西组合在一起。NM

输出将使用与输入相同的分隔符。 GNUcut支持--output-delimiter=STRING设置不同分隔符的选项,但我认为其他人不会这样做。 FreeBSDcut包括-w按空格分割选项更接近awk默认情况。如果您希望在其他地方实现这些行为之一,那么在之前/之后转换分隔符可能是您最好的选择。

答案2

后续行动迈克尔·霍默的回答:

ksh为了避免使用支持进程替换( , zsh, )的 shell 多次读取文件bash

 tee < Precipitation.csv >(cut -d, -f1-20 > aaa1) >(cut -d, -f21-40 > aaa2) | 
   cut -d, -f41- > aaa3

答案3

perl

perl -F',' -anle 'print join ",", @F[0..19]' Precipitation.csv > aaa1
perl -F',' -anle 'print join ",", @F[20..39]' Precipitation.csv > aaa2
perl -F',' -anle 'print join ",", @F[40..99]' Precipitation.csv > aaa3

答案4

这提供了更好的性能,因为我们只读取输入文件一次

awk '{out1=$1; for(i=2; i<=20; i++) {out1 = (out1 FS $i)}
  out2=$21; for(i=22; i<=40; i++) {out2=(out2 FS $i)}
  out3=$41; for(i=42; i<=100; i++) {out3=(out3 FS $i)}
  print out1 > "aaaaa1"; print out2 > "aaaaa2"; print out3 > "aaaaa3"}' Precipitation.csv

或者您可以在以下命令中键入所有字段编号。将“...”替换为所有必填字段编号

awk '{print $1,$2,$3,...$19,$20 > "aaaaa1";
  print $21,$22,$23,...$39,$40 > "aaaaa2";
  print $41,$42,$43,...$99,$100 > "aaaaa3"}' Precipitation.csv

相关内容