2013-03-18 24 views
0

我有一个看起来像这样的“MM/YYYY,数据”的格式输入数据:单柱,以多列可调行列数AWK

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可以将输出的n列中的“位置X”的单列数据块分割为“位置Y”?

我得到了输出,但它不正确以文本换行方式水平运行单个输入文件的输出或像这样“蛇行” - 位置1 mm/yyyy,data1 data2等位置2 mm/yyyy, DATA1 DATA2等地理位置3月/年,DATA1 DATA2等

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

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 

谢谢!

回答

0

另一个awk的你可以尝试:

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 
+0

好的,它的工作原理。我必须弄清楚如何为每个“位置”或列标题仅打印$ 2或第二列。任何想法?目前,它打印1美元和2美元。谢谢, – user2100039 2013-03-19 15:37:34

+0

@ user2100039:增加了快速修复 – Scrutinizer 2013-03-19 15:47:27

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 
  • 上面的行不会匹配硬编码的“位置”,但对于非数字标题(wo rks for“locations”)
  • 276,277我不知道这是什么意思。但上面的单行将为每个块(在您的示例中的位置),打印最多276行。如果行号小于276,则只打印实际的行数。

您可以稍微调整一下,以适应您的需求。

祝你好运。

+0

对不起,列标题“位置1,等”是这个例子,但实际上他们是改变,因此“位置”从来没有出现在输入文件名。它可以只搜索任何长度的字符串吗? – user2100039 2013-03-18 17:52:36

+0

在输入文件中,数据行= 276,包括标题行= 277.再次感谢 - – user2100039 2013-03-18 17:54:29

+0

@ user2100039那么在您的真实数据中,“位置”是什么?遵循某种模式?无论如何,我认为我的单线让你开始。 – Kent 2013-03-18 17:56:21

1

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

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

既然你知道有多少行中的每个位置,计算出的位置号码与:

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

谢谢 - 实际文件中的“位置”标题不使用单词“位置”,而是它们是唯一的“位置”,如Flatiron,Wolfbog,Mesavista等。数据行是= 276 +标题对于需要打印为新列的每个数据块。谢谢! – user2100039 2013-03-18 19:05:19

+0

glenn-当我运行此代码时出现“非法变量名称”错误,并在分别运行numcols代码以查找位置数量时出现相同的错误消息。想法? – user2100039 2013-03-19 15:33:29

+0

真的吗?你用什么shell(bash/csh/...)?向我们展示您*实际执行的代码。请注意,外部括号加倍,内部括号是单个 – 2013-03-19 16:54:32