单列到多列可调行和列AWK

时间:2013-03-18 17:19:26

标签: awk

我输入的数据看起来像是“mm / yyyy,data”格式:

Location 1
08/2012, 44.1
09/2012, 34.2
10/2012, 24.3
11/2012, 14.4
12/2012, 04.5
01/2013, 14.6
02/2013, 24.7
Location 2
08/2012, 33.1
09/2012, 44.2
10/2012, 55.3
11/2012, 66.4
12/2012, 77.5
01/2013, 88.6
02/2013, 11.7
Location 3
08/2012, 35.1
09/2012, 45.2
10/2012, 55.3
11/2012, 66.4
12/2012, 77.5
01/2013, 71.6 
02/2013, 19.7
Location 4
etc
etc

我正在使用awk脚本 -

awk'} printf(NR%276 == 0)? $ 0“\ n”:$ 0“\ t”}'inputfile(我使用的是NR%276,因为这是每个新重复列的列长度或上面部分所示原始数据中的“位置”)。 awk可以将单个col数据块从“位置X”划分为n个输出中的“位置Y”吗?

我正在获取输出但不正确以文本换行方式水平运行单个col输入文件的输出或者像这样“蜿蜒” - 位置1 mm / yyyy,data1 data2 etc位置2 mm / yyyy,data1 data2 etc位置3 mm / yyyy,data1 data2等。

相反,我需要输出数据类似于此但是对于276行和大约150列/位置或输入文件中276行的“位置”数据的最后一个单列块(上面缩短的示例)。将行数增加到277会有所帮助,例如2013年3月或> 150个地点。

Location 1        Location 2        Location 3
08/2012, 44.1     08/2012, 33.1     08/2012, 35.1
09/2012, 34.2     09/2012, 44.2     09/2012, 45.2
10/2012, 24.3     10/2012, 55.3     10/2012, 55.3
11/2012, 14.4     11/2012, 66.4     11/2012, 66.4
12/2012, 04.5     12/2012, 77.5     12/2012, 77.5
01/2013, 14.6     01/2013, 88.6     01/2013, 71.6
02/2013, 24.7     02/2013, 11.7     02/2013, 19.7

谢谢!

3 个答案:

答案 0 :(得分:1)

试试这个单行:

 awk '/^Location/{j=0;++i}{l[i,++j]=$0}END{for(m=1;m<=j;m++){for(n=1;n<=i;n++)printf l[n,m] (n==i?"":"\t");print ""}}' file

注意

  • 上面一行将您的单列输入转换为3列输出,但未处理您的276 rows内容。 (我认为我们不需要进行这种计算。)
  • 在输出中,列tab分开。
  • 行和列不是硬编码的,您可以使用真实数据进行测试

使用您的数据进行测试:

kent$  awk '/^Location/{j=0;++i}{l[i,++j]=$0}END{for(m=1;m<=j;m++){for(n=1;n<=i;n++)printf l[n,m] (n==i?"":"\t");print ""}}' file      
Location 1      Location 2      Location 3
08/2012, 44.1   08/2012, 33.1   08/2012, 35.1
09/2012, 34.2   09/2012, 44.2   09/2012, 45.2
10/2012, 24.3   10/2012, 55.3   10/2012, 55.3
11/2012, 14.4   11/2012, 66.4   11/2012, 66.4
12/2012, 04.5   12/2012, 77.5   12/2012, 77.5
01/2013, 14.6   01/2013, 88.6   01/2013, 71.6 
02/2013, 24.7   02/2013, 11.7   02/2013, 19.7

编辑以发表评论

 awk '!/^[0-9]/{j=0;++i}{l[i,++j]=$0}END{for(m=1;m<=277&&m<=j;m++){for(n=1;n<=i;n++)printf l[n,m] (n==i?"":"\t");print ""}}' file 
  • 上述行与硬编码的“位置”不匹配,但对于非数字标题(也适用于“地点”)
  • 276,277我不知道这是什么意思。但上面的单行将为每个块(在您的示例中的位置),打印最多276行。如果行号小于276,则只打印实际行数。

您可以稍微调整一下,以满足您的需求。

祝你好运。

答案 1 :(得分:1)

假设每个位置的数据行数相同:

numcols=$(tac input_file | awk '$1 == "Location" {print $2; exit}')
pr -t -s --columns=$numcols input_file

由于您知道每个位置有多少行,因此请计算位置数:

numcols=$(( $(wc -l < input_file) / 277 ))

答案 2 :(得分:0)

你可以试试另一个问题:

awk '!/^[0-9]/{n=0} {n++; A[n]=A[n] (A[n]?OFS:x) $0} END{for(i=1; i<=n; i++) print A[i]}' OFS='\t' file

仅在每个位置打印第二列:

awk '!/^[0-9]/{n=0} {n++; A[n]=A[n] (A[n]?OFS:x) $2} END{for(i=1; i<=n; i++) print A[i]}' OFS='\t' file