2014-01-22 41 views
2

我想用awk连续评估两个文件。在第一个文件的末尾,我正在读取一个日期,并将该日期用作评估第二个文件的输入。不幸的是,我在理解如何检测读取日期的第一个文件的结尾时遇到了一些问题,并继续评估下一个文件。我发现了一些答案,如FNR == NR,不幸的是,我无法正确实施它们。我通过硬编码行数来尝试穷人的解决方案。然而,这不是一件非常聪明的事情。我仍然有问题处理的第二个文件,但:使用AWK连续处理两个不同的文件

BEGIN initalize the counters 



    { 
    if(NR==FNR) <<<<<< this is needed to run properly, only NR==FNR fails, why ?!  
    {  
      # file_1  
      do -> from the last line of the first file extract a date 

      next << what is the meaning of this ?? 
    }       

    { 
      # file_2 
      do -> read every line of the second file 
      and sum up the values form one of the colums 


    } 


    } 


    END { divide the sum accumulated form file=2 
      by the time calculated form the last line of file=1} 

# for calling the script use : 
awk -f SCRIPT file_1 file_2 

#example files 
# file1 last line 
version 1.5 code 11 mpi start /01/12/2014/ 18:33:12 end /01/12/2014/ 20:05:12 

#file2 

    1.28371E-05 0.2060 0.2060 -8 -8 0 0 0 
    1.91616E-05 0.1927 0.1927 -7 -8 0 0 0 
    1.27306E-05 0.1567 0.1567 -6 -8 0 0 0 
    2.11623E-05 0.1523 0.1523 -5 -8 0 0 0 
    1.67914E-05 0.1721 0.1721 -4 -8 0 0 0 
    1.47247E-05 0.1851 0.1851 -3 -8 0 0 0 
    1.32049E-05 0.1919 0.1919 -2 -8 0 0 0 
    1.81256E-05 0.2130 0.2130 -1 -8 0 0 0 
    2.63500E-05 0.1745 0.1745 0 -8 0 0 0 
    1.99232E-05 0.1592 0.1592 1 -8 0 0 0 
    2.08924E-05 0.1537 0.1537 2 -8 0 0 0 
    2.44922E-05 0.1459 0.1459 3 -8 0 0 0 
    2.53759E-05 0.1902 0.1902 4 -8 0 0 0 
    2.30230E-05 0.1708 0.1708 5 -8 0 0 0 
    2.10723E-05 0.1636 0.1636 6 -8 0 0 0 
    1.86613E-05 0.1915 0.1915 7 -8 0 0 0 
    2.05359E-05 0.1649 0.1649 8 -8 0 0 0 
    1.09533E-05 0.1765 0.1765 -8 -7 0 0 0 
    1.56917E-05 0.1740 0.1740 -7 -7 0 0 0 
    1.52199E-05 0.2145 0.2145 -6 -7 0 0 0 
    ..... 

我希望得到任何帮助, 预先感谢您

亚历

+1

这听起来像是你想要的东西在awk中绝对是微不足道的,但通过'在第一个文件的末尾我正在阅读一个日期'来说明你的意思,因为有几种可能性,例如,你正在从一个文件中读取它(在这种情况下,为什么不在脚本运行之前做)或从变量中获取它(同上)或提示某人输入它或其他内容,并且正确的解决方案取决于它是什么你正在做那一步。 –

+0

我想为此造成的不便表示歉意。我在读一个文件,说文件A.这个文件在其结尾包含日期和时间。我读了这段时间,并进一步进行到第二个文件,在这里我使用时间作为一些表达式的输入。所以要说形成第一个文件,我提取了一个变量,其中的值用于处理第二个文件。 –

+0

我张贴在答案中,看看你是否需要这些。如果不是,请发布一个脚本来演示您的问题以及一些示例输入广告预期输出。您发布的脚本似乎有很多复杂性,与您所描述的问题完全无关,所以如果我们不需要通读所有内容才能看到实际问题,它会帮助我们帮助您。 –

回答

1

这听起来像所有你需要的是这样的:

awk ' 
NR==FNR { 
    do file1 stuff 
    date = $0 
    next 
} 
{ 
    do file2 stuff using the variable "date" which is set to the last line of file1 
} 
' file1 file2 

如果这不是你所需要的,张贴一些样品的输入和预期的输出,以帮助澄清你想要做什么。

+0

我试着简化我的示例代码,以便我的问题变得更容易理解。其实,如果我正确理解你的想法,NR == FNR可以确保我仅阅读第一个文件。因为对于第一个文件,本地计数器FNR和全局计数器NR是相等的。对于第二个文件,它们被移动第一个文件的行数。但是,我如何检测第一个文件的结尾? –

+0

在gawk中你可以使用'ENDFILE',但到目前为止我没有看到任何东西可以表明你需要这个。在我发布的示例中,当读取file2和END部分时,变量'date'将填充第一个文件最后一行的值。那么,为什么你不需要这些? –

+0

嗨,Ed,我认为你的想法没问题,当我改变NR == FNR为if语句if(NR == FNR)我不知道为什么,问题就消失了。而且,什么是“下一个”呢? –

1

为此,您可以通过两种方式:

  • 缓冲每一行并检查时间FNR==1

喜欢的东西:

awk 'FNR==1 && NR!=1{print line,"is last in first file"}NR>1{print line}{line=$0} ' 
  • 如果您正在使用gawk可以使用ENDFILE块。

或者:

gawk '{print $0} ENDFILE && !f {print $0,"is last line in first file", f=1}' 
+0

嗨,感谢您的帮助。可悲的是,它没有按预期工作,代码最终将整个文件打印在屏幕上。我也尝试根据你的建议修改我的脚本,但无济于事。 –

1

我设置的命令行变量来实现:

awk 'F==1 {print "one: ", $0} F==2 {print "two: ", $0}' F=1 one.txt F=2 two.txt 

每当遇到x = y形式的东西,它设置变量x的awk到y。

+0

嗨,我已经更新了我的脚本。其实你提出的是以正确的方向。表达式F == 1 F == 2确保我正在阅读正确的文件。但是,如何检测第一个文件的结尾。我可以使用正则表达式(F == 1 &&/regex /),但是,我认为存在更优雅的解决方案。 –

+0

在Gnu Awk中有一个'ENDFILE {}'规则。所以你可以试试'ENDFILE {if(FNR == NR)date = $ 0}' –

+0

@AlexanderCska你真的需要知道最后一行吗?你不能只在第一个文件的块中保存一个变量'lastLineFile1 = $ 0',并且在'END'子句中从'lastLineFile1'中提取所需的日期/时间? – Jan

1

如果你只是想从第一个文件的最后一行,并通过AWK进行处理的第二个文件的内容之日起,就可以做到这一点,让生活更轻松:

(tail -1 firstfile; cat secondfile) | awk 'something' - 

当然,如果日期是不完全的最后一行,你可以做这样的事情:

(grep ^Date firstfile; cat secondfile) | awk 'something' - 

这样你只会有一个单一的“文件/流”在awk来处理和第一线将是你的约会。