将行提取到根据每个非空第一列中的字符串命名的单独文件中

将行提取到根据每个非空第一列中的字符串命名的单独文件中

我有一个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).

相关内容