l0b*_*0b0 3 shell text-processing
这是另外两个问题的组合(如何按每行前缀拆分文件以及如何根据列拆分文件,包括标题)。我想从以下内容开始input.csv:
id,first,second,third
1,a,b,c
333,b,b,b
1,d,e,f
2,d,e,f
1,c,d,e
333,a,a,a
[more lines in the same format]
Run Code Online (Sandbox Code Playgroud)
到此内容1.csv:
id,first,second,third
1,a,b,c
1,d,e,f
1,c,d,e
Run Code Online (Sandbox Code Playgroud)
,此内容在2.csv:
id,first,second,third
2,d,e,f
Run Code Online (Sandbox Code Playgroud)
,以及此内容333.csv:
id,first,second,third
333,b,b,b
333,a,a,a
Run Code Online (Sandbox Code Playgroud)
, 那是:
N.csv.这也必须非常快,所以while read循环不会切断它。
这个 GNU awk 命令可以解决问题:
awk -F ',' 'NR==1{h=$0; next};!seen[$1]++{f=$1".csv"; print h > f};{f=$1".csv"; print >> f; close(f)}' input.csv
Run Code Online (Sandbox Code Playgroud)
警告:如果第一个字段中有转义的逗号,这将不起作用。其他领域的逗号应该可以正常工作。
解释:
-F ','(字段分隔符)确保$1等引用 CSV 列而不是空格分隔值。NR==1{h=$0; next}NR==1通过将完整的标题行存储在变量h( h=$0) 中并跳过行 ( next) 来特别对待第一行 ( )。!seen[$1]++{f=$1".csv"; print h > f}通过将后跟存储到文件名变量并将标头保存到该文件 ( )来处理任何$1特殊 ( !seen[$1])的第一次出现。$1.csvfprint h > f{f=$1".csv"; print >> f; close(f)}将当前行添加到文件 ( print >> f) 并关闭文件描述符 ( close(f)) 以避免在处理完具有特定 ID 的所有行后保留它。奖励:如果您$1用另一个字段替换它应该按照您的预期执行:在该列中为每个唯一值创建一个文件,其中包含给定列中包含该值的行。