2

您好 stackoverflow 用户!

一般来说,我想调整我正在使用的脚本,只是为了让它对丢失的数据更加不敏感。我的示例数据如下所示(带有标题的制表符分隔的 csv 文件):

ColA    ColB    ColC
6   0   0
3   5.16551 12.1099
1   10.2288 19.4769
6   20.0249 30.6543
3   30.0499 40.382
1   59.9363 53.2281
2   74.9415 57.1477
2   89.9462 61.3308
6   119.855 64.0319
4   0   0
8   5.06819 46.8086
6   10.0511 60.1357
9   20.0363 71.679
6   30.0228 82.1852
6   59.8738 98.4446
3   74.871  100.648
1   89.9973 102.111
6   119.866 104.148
3   0   0
1   5.07248 51.9168
2   9.92203 77.3546
2   19.9233 93.0228
6   29.9373 98.7797
6   59.8709 100.518
6   74.7751 100.056
3   89.9363 99.5933
1   119.872 100

我使用awk在其他地方找到的脚本,如下所示:

awk 'BEGIN { fn=0 }
NR==1 { next }
NR==2 { delim=$2 }
$2 == delim {
    f=sprintf("file_no%02d.txt",fn++);
    print "Creating " f
}

{ print $0 > f }'

这给了我想要的输出 - 省略第一行,找到第二列并设置分隔符 - 在这个例子中它将是'0':

file_no00.txt
6   0   0
3   5.16551 12.1099
1   10.2288 19.4769
6   20.0249 30.6543
3   30.0499 40.382
1   59.9363 53.2281
2   74.9415 57.1477
2   89.9462 61.3308
6   119.855 64.0319

file_no01.txt
4   0   0
8   5.06819 46.8086
6   10.0511 60.1357
9   20.0363 71.679
6   30.0228 82.1852
6   59.8738 98.4446
3   74.871  100.648
1   89.9973 102.111
6   119.866 104.148

    file_no02.txt
3   0   0
1   5.07248 51.9168
2   9.92203 77.3546
2   19.9233 93.0228
6   29.9373 98.7797
6   59.8709 100.518
6   74.7751 100.056
3   89.9363 99.5933
1   119.872 100

为了使脚本更健壮(假设删除了 0 的行),如果该值低于 0 拆分文件,我需要根据行 'n+1' 和 'n' 的减去值来拆分文件,所以基本上如果(value_row_n+1)-value_row_n < 0那时分割文件。当然,我还需要维护文件命名。首选方式是bash随用随awk用。有什么建议吗?提前致谢!

干杯!

4

2 回答 2

3

这是您可以使用的 awk 命令:

cat file
ColA    ColB    ColC
3       5.16551 12.1099
1       10.2288 19.4769
6       20.0249 30.6543
3       30.0499 40.382
1       59.9363 53.2281
2       74.9415 57.1477
2       89.9462 61.3308
6       119.855 64.0319
8       5.06819 46.8086
6       10.0511 60.1357
9       20.0363 71.679
6       30.0228 82.1852
6       59.8738 98.4446
3       74.871  100.648
1       89.9973 102.111
6       119.866 104.148
1       5.07248 51.9168
2       9.92203 77.3546
2       19.9233 93.0228
6       29.9373 98.7797
6       59.8709 100.518
6       74.7751 100.056
3       89.9363 99.5933
1       119.872 100
awk 'NR == 1 {
  next
}
!p || $2 < p {
   f = sprintf("file_no%02d.txt",fn++);
   print "Creating " f
}
{
   p = $2;
   print $0 > f
}' file
于 2013-09-10T21:17:52.067 回答
2

我建议对您当前的脚本进行一些小的修改:

awk 'BEGIN { fn=0; f=sprintf("file_no%02d.txt",fn++); print "Creating " f }
NR==1 { next }
NR==2 { delim=$2 }
$2 - delim < 0 {
    f=sprintf("file_no%02d.txt",fn++);
    print "Creating " f
}

{ print $0 > f; delim = $2 }' infile

首先,在开始处理之前创建第一个文件名。

其次,在最后一个条件下保存当前行的值以与下一行的值进行比较。

第三,代替与零的比较,在前一个值和当前值之间进行减法,以检查结果是否小于零。

它产生:

==> file_no00.txt <==
6   0   0
3   5.16551 12.1099
1   10.2288 19.4769
6   20.0249 30.6543
3   30.0499 40.382
1   59.9363 53.2281
2   74.9415 57.1477
2   89.9462 61.3308
6   119.855 64.0319

==> file_no01.txt <==
4   0   0
8   5.06819 46.8086
6   10.0511 60.1357
9   20.0363 71.679
6   30.0228 82.1852
6   59.8738 98.4446
3   74.871  100.648
1   89.9973 102.111
6   119.866 104.148

==> file_no02.txt <==
3   0   0
1   5.07248 51.9168
2   9.92203 77.3546
2   19.9233 93.0228
6   29.9373 98.7797
6   59.8709 100.518
6   74.7751 100.056
3   89.9363 99.5933
1   119.872 100
于 2013-09-10T21:15:29.983 回答