我想将大约 500 万行(300 列)重新排列成组。
数据如下所示:其中在不同年份(第 1 列)使用仪器(第 3 列)在不同地点(顶行第 4 列开始的列标题)进行了各种实验(第 2 列)。矩阵中的数字(第 2 行开始,第 4 列开始)表示实验成功的实例数。
我想要的是重新排列行
输入
345 346 347 348 349 350 351 352
2014 Exp1 IBM 24 45 22
2014 Exp2 LEN 23 32 34
2014 Exp3 LEN 2 34 34
2014 Exp4 IBM 34 44 43
2014 Exp5 IBM 2 45 51 45
2014 Exp6 IBM 34 23 54
2014 Exp7 IBM 23 23 24
2014 Exp8 IBM 34 45 56
2014 Exp9 LEN 24 45 45
2014 Exp10 LEN 43 45 32
2015 Exp11 IBM 34 55 33 34
2015 Exp12 IBM 1 33 4 5
2015 Exp13 IBM 43 55 34 43
2015 Exp14 IBM 45 32 43 4
2015 Exp15 IBM 23 4 5
2015 Exp16 IBM 32 34 43
2015 Exp17 IBM 32 34 46
2015 Exp18 LEN 32 54 67
2015 Exp19 SCL 56 6 4 45 56
2015 Exp20 LEN 67 56 76
2015 Exp21 LEN 45 56 65
2015 Exp22 SCL 45 55 54
2015 Exp23 SCL 4 55 45
我想要的是将行重新排列成组,这样
1) 同一年内 2) 使用同一仪器
创建组,以便
每个组至少有 3 个共同地点,每个地点至少有 20 次成功的实验。
请求的输出
345 346 347 348 349 350 351 352
1 2014 Exp1 IBM 24 45 22
1 2014 Exp4 IBM 34 44 43
1 2014 Exp7 IBM 23 23 24
2 2014 Exp2 LEN 23 32 34
2 2014 Exp9 LEN 24 45 45
2 2014 Exp10 LEN 43 45 32
3 2014 Exp5 IBM 2 45 51 45
3 2014 Exp6 IBM 34 23 54
3 2014 Exp8 IBM 34 45 56
4 2015 Exp11 IBM 34 55 33 34
4 2015 Exp13 IBM 43 55 34 43
4 2015 Exp14 IBM 45 32 43 4
5 2015 Exp16 IBM 32 34 43
5 2015 Exp17 IBM 32 34 46
6 2015 Exp18 LEN 32 54 67
6 2015 Exp20 LEN 67 56 76
6 2015 Exp21 LEN 45 56 65
7 2015 Exp19 SCL 56 6 4 45 56
7 2015 Exp22 SCL 45 55 54
2014 Exp3 LEN 2 34 34
2015 Exp12 IBM 1 33 4 5
2015 Exp15 IBM 23 4 5
2015 Exp23 SCL 4 55 45
这是我尝试过的。
awk ' NR>1{ for (i=4;i<=NF;i++) if ($i!="") arr1[$1,$2,$3]=$i ; next }
$1,$2,$3 in arr1 {
for (j=1;j<length(arr1);j++))
{if (arr1[j] > 20)
group++;
END {
for (j in n) {
print group, arr1[j]
}
}' input input
答案1
根据实际数据格式和其他问题的一些随机提示......
数据字段如何分隔? (前三个空格给人的印象是中间有一个制表符,而最后一列似乎是空格分隔的。)您应该注意,如果您的字段分隔符是按照默认值定义的,则 culumns 4-N 的列信息会丢失。所以你的代码逻辑有严重缺陷。
如果你有不TAB 分隔符但所有空白都可以使用 GNUawk
的FIELDWIDTHS
功能来访问数据(包括丢失的“空白”数据,正如您似乎试图实现的那样)。
如果前三个分隔符有制表符,其余分隔符有空格,则应显式定义FS="\t"
,以便您可以直接处理字段 1-3 并在最终数据中保留完整的间距(您可以将其作为一个整体作为字段 4 进行处理) ),这样就可以很容易地找到“空白数据”。
如果您动态创建数据子集,对这些子集进行操作,然后连接各个子集,则可能会进一步使处理变得更加容易。要分离文件中的数据,取决于,例如,年和乐器你可以写:
awk '{ print > "set_" $1 "_" $3" }' input
它将创建名为例如set_2015_LEN
或set_2014_IBM
包含相应条目的文件。
识别“匹配数字列集”的最终任务取决于前面提到的主题;例如,如果最后第八个数据列可以作为一个固定长度的实体来处理,那么使用sort
具有适当定义的键规范的实用程序就足够了(参见sort
的选项-k
)。
(顺便说一句:对于复合索引测试,$1,$2,$3 in arr1
您必须编写($1,$2,$3) in arr1
。)