2014-01-22 38 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來處理和第一線將是你的約會。