我举例说明了我需要做的事情:
INPUT:
name value1 value2 value3
john xxxxx yyyyy qqqqqq
john xxxxx ddddd vvvvvv
john mmmmm jjjjj llllll
paul xxxxx yyyyy qqqqqq
paul ccccc ccccc dddddd
我需要在第一列中根据相同的名称保留标题并拆分成文件。 我需要根据第一栏继续命名我的输出文件。
输出:
FILE1 :john.tsv
name value1 value2 value3
john xxxxx yyyyy qqqqqq
john xxxxx ddddd vvvvvv
john mmmmm jjjjj llllll
FILE2 :paul.tsv
name value1 value2 value3
paul xxxxx yyyyy qqqqqq
paul ccccc ccccc dddddd
INPUT和OUTPUT文件是制表符分开的。标题总是一样的。
我的解决方案非常复杂且缓慢:
head -1 INPUT > header
awk 'NR>1{print $1}' | sort | uniq > names
while read line
do grep $line INPUT | cat header - > $line.tsv
< names
done
答案 0 :(得分:5)
使用awk
,我们可以编写类似的内容,
$ awk 'NR == 1{header = $0; next}
!($1 in filename){ print header > ($1".tsv") }
NR > 1 { print $0 > ($1".tsv"); filename[$1] }' file
它的作用是什么?
NR == 1{header = $0}
如果读取的记录数为1
,则这是标题,将其保存在header
中供以后使用。
NR > 1 { print $0 > ($1".tsv"); filename[$1] }
如果我们已经阅读了多条记录,请将该行的内容打印到文件名$1
,即第一列。
filename[$1]
我们将文件名保存在由文件名索引的关联数组中。该数组用于打印标题。 ($1 in filename){ print header > ($1".tsv") }
如果我们在filename
数组中找不到当前文件名,那么它就是第一次出现。所以我们将标题打印到文件中。
修改强>
如果要对第二列上的文件进行排序,那么我们可以先对它们进行排序,然后将它们传递给awk
,例如,
$ sort -n -k2 file | awk ....
-n
数字排序。-k2
排序第二把钥匙。如果标题也是数字,则可能无效。
答案 1 :(得分:3)
到目前为止发布的所有答案都存在使它们易碎和/或不可移植的问题(例如,使用getline而不检查结果,输出重定向的右侧未使用,使用特定于gawk的功能,而不是关闭完成后的每个输出文件)和/或不必要的复杂。
要按前两列对输入文件进行排序,同时保留标题为:
$ awk -v OFS='\t' '{print (NR>1), $0}' file | sort | cut -f2-
name value1 value2 value3
john mmmmm jjjjj llllll
john xxxxx ddddd vvvvvv
john xxxxx yyyyy qqqqqq
paul ccccc ccccc dddddd
paul xxxxx yyyyy qqqqqq
并且可靠,便携,高效地打印输入,包括标题行以分隔基于第一列命名的文件:
$ cat tst.awk
NR==1 { hdr=$0; next }
$1 != prev {
close(out)
out = $1 ".tsv"
print hdr > out
prev = $1
}
{ print > out }
所以把它们放在一起就是:
awk -v OFS='\t' '{print (NR>1), $0}' file | sort | cut -f2- | awk -f tst.awk
答案 2 :(得分:2)
类似于@ nu11p01n73R的回答,在脚本中添加了数据部分的排序
$ awk 'NR==1{h=$0; next}
!p[$1]++{print h > $1}
{print | "sort -k2 >> " $1}' file
$ head paul john
==> paul <==
name value1 value2 value3
paul ccccc ccccc dddddd
paul xxxxx yyyyy qqqqqq
==> john <==
name value1 value2 value3
john mmmmm jjjjj llllll
john xxxxx ddddd vvvvvv
john xxxxx yyyyy qqqqqq