我有一个mappings.csv
如下所示的 csv。我想将记录块提取到与具有非空第一个字段的每个记录相关的单独文件中。文件显示在 后mappings.csv
。
$ cat mappings.csv
TEST1,,,a,a,a,a
,,,b,b,b,b
,,,c,c,c,c
TEST2,,,aa,aa,aa,aa
,,,bb,bb,bb,bb
,,,cc,cc,cc,cc
,,,dd,dd,dd,dd
TEST3,,,aaa,aaa,aaa,aaa
,,,bbb,bbb,bbb,bbb
输出文件基于mappings.csv
如下:
$ cat TEST1.csv
TEST1,,,a,a,a,a
,,,b,b,b,b
,,,c,c,c,c
$ cat TEST2.csv
TEST2,,,aa,aa,aa,aa
,,,bb,bb,bb,bb
,,,cc,cc,cc,cc
,,,dd,dd,dd,dd
$ cat TEST3.csv
TEST3,,,aaa,aaa,aaa,aaa
,,,bbb,bbb,bbb,bbb
我可以使用 awk 打印具有非空第一个字段的行,但无法弄清楚如何扩展和打印后续记录直到下一个非空第一个字段:
$ awk -F',' '$1' mappings.csv
TEST1,,,a,a,a,a
TEST2,,,aa,aa,aa,aa
TEST3,,,aaa,aaa,aaa,aaa
这个问题的另一个方面是将结果分离到单独的文件中。我可以做的一件事是使用匹配的记录号打印出两者之间的行。有点像这样:
$ awk -F',' '$1 {print NR}' mappings.csv
1
4
8
答案1
尽管之前已经提出并回答过非常类似的问题,例如
我找不到精确的重复项,其中文件名只能从指定列的非空值中获取。所以给出:
$ cat mappings.csv
TEST1,,,a,a,a,a
,,,b,b,b,b
,,,c,c,c,c
TEST2,,,aa,aa,aa,aa
,,,bb,bb,bb,bb
,,,cc,cc,cc,cc
,,,dd,dd,dd,dd
TEST3,,,aaa,aaa,aaa,aaa
,,,bbb,bbb,bbb,bbb
然后
awk -F, '$1 != "" {close(f); f = $1 ".csv"} {print > f}' mappings.csv
结果是
$ head TEST*
==> TEST1.csv <==
TEST1,,,a,a,a,a
,,,b,b,b,b
,,,c,c,c,c
==> TEST2.csv <==
TEST2,,,aa,aa,aa,aa
,,,bb,bb,bb,bb
,,,cc,cc,cc,cc
,,,dd,dd,dd,dd
==> TEST3.csv <==
TEST3,,,aaa,aaa,aaa,aaa
,,,bbb,bbb,bbb,bbb
第一个操作关闭名为的文件f
(如果有打开的文件),然后f
通过将第一个字段的(非空)值$1
与 suffix连接来构造一个新值.csv
。第二个操作将记录打印到名称为变量(当前)值的文件中f
。注意如果为空会报错f
,如果有任何行都会出现这种情况前第一个非空值$1
。
某些 awk 实现可能会为您负责关闭文件,在这种情况下您不需要显式close(f)
.