2017-06-21 101 views
0

兩次我有一個awk腳本像如何使用STDIN從管

awk 'FNR==NR {col1[$1]++; col2[$2]++; next} {print $0, col2[$2] "/" length(col1)}' input input 

但如果我有很多文件,需要使用這個腳本連接起來的文件一起想:

cat *all_input | awk 'FNR==NR {col1[$1]++; col2[$2]++; next} {print $0, col2[$2] "/" length(col1)}' STDIN STDIN 

不起作用。如何從管道使用兩次STDIN?

+0

你的問題根本沒有意義。如果你正在通過stdin捕捉許多文件來awk?爲什麼你需要在結束時再次傳遞stdin。你有理解錯誤 – Inian

+0

..你爲什麼在首先提出另一個要求後完全改變了這個問題? – Inian

+0

對錯描述抱歉,但似乎|進入<(...),兩次完美無缺。腳本看起來:awk'FNR == NR {col1 [$ 1] ++; COL2 [$ 2] ++;接下來} {打印$ 0 COL2 [$ 2] 「/」 長度(COL1)} <(貓*文件)<(貓*文件) – Geroge

回答

4

你並不需要使用管道。如果使用的是bash使用process-substitution as <(cmd)即實現其中的處理(命令的一些序列)的輸入或輸出顯示爲一個臨時文件的重定向。

awk 'FNR==NR {col1[$1]++; col2[$2]++; next} {print $0, col2[$2] "/" length(col1)}' <(cut -f3 5- input) <(cut -f3 5- input) 
+0

謝謝伊恩 - 但是如果我有很多文件,需要做如下操作:cat * files | awk ....... STDIN SDTIN? – Geroge

+0

@Geroge:上述評論的要求不明確。用一個例子來解釋,並將其添加到問題 – Inian

+0

有關過程替換的知識!!但我幾乎沒有改變我的問題來連接我的文件.. – Geroge

0

我不知道這是否可以幫助,因爲我不是一個awk專家,但任何Linux應用程序(包括AWK)可以讀取的/ proc /自/ FD/0

直標準輸入

請注意,這種方式不如open(0)便攜,只能在具有可讀procfs(幾乎所有Linux發行版)的Linux上運行。

如果應用程序允許並行文件描述符消耗,可以兩次打開該文件描述並從中讀出兩次。

在路徑指定訪問應用的PID。

1

答案How to use STDIN twice from pipe是「你不能」。如果你想兩次使用stdin的數據,那麼當你第一次讀它時,你需要將它保存在某個地方,以便下次使用它。例如:

$ seq 3 | 
awk ' 
    BEGIN { 
     if (("mktemp"|getline line) > 0) tmp=line; else exit 
     ARGV[ARGC]=tmp; ARGC++ 
    } 
    NR==FNR { print > tmp } 
    { print FILENAME, NR, FNR, $0 } 
' - 
- 1 1 1 
- 2 2 2 
- 3 3 3 
/var/folders/11/vlqr7jmn6jj3fglyl12lj0l00000gn/T/tmp.Y03l9pS7 4 1 1 
/var/folders/11/vlqr7jmn6jj3fglyl12lj0l00000gn/T/tmp.Y03l9pS7 5 2 2 
/var/folders/11/vlqr7jmn6jj3fglyl12lj0l00000gn/T/tmp.Y03l9pS7 6 3 3 

或者您可以將它存儲在內部數組或字符串中,並在稍後從中讀取它。

說了這麼多,您的具體問題,並不需要任何特別的,只是一個簡單的:

cat *all_input | awk 'FNR==NR {col1[$1]; col2[$2]++; next} {print $0, col2[$2] "/" length(col1)}' - *all_input 

會做,但除非你的文件是巨大的你真正需要的是商店,它-在 - 陣列辦法:

awk '{ col1[$1]; col2[$2]++; f0[NR]=$0; f2[NR]=$2 } 
END { 
    for (nr=1; nr<=NR; nr++) { 
     print f0[nr], col2[f2[nr]] "/" length(col1) 
    } 
}' *all_input 
+0

嗨,埃德,謝謝你的好點。你理解我的問題是正確的。 awk'FNR == NR {a [$ 90]; b [$ 1] + =!c [$ 1,$ 90] ++; next} {print b [$ 1]「可以將數組放入數組中: /「length(a)」\ t「(b [$ 1]/length(a))* 100}'<(cat * anot_tmp1.tsv)<(cat * anot_tmp1.tsv)??我想申請您的解決方案的大文件感謝,而不是使用替代.. – Geroge

+0

對不起,我不明白你的問題。如果你有一個巨大的文件,爲什麼要將它們的內容存儲在一個數組中,而不是直接從文件中使用數據?你選擇了一個答案,所以你應該問問提供答案的人,而不是像我這樣提供了錯誤答案的人 - 也許他們會明白你的意思,並對你的答案進行調整。 –