2017-05-14 51 views
2

我有一個單獨的文件,其中包含第一個和第二個列,其中包含項目代碼和名稱,然後是第三個列到第十二個列,其中包含連續10天的消耗數量。 現在我需要將它轉換成10個不同的文件。在每個第一和第二欄應該是相同的項目代碼和項目名稱和第三列將包含在每一天的消費量..awk命令使用for循環打印多列

輸入文件:

Code | Name | Day1 | Day2 | Day3 |... 

10001 | abcd | 5 | 1 | 9 |...  
10002 | degg | 3 | 9 | 6 |...  
10003 | gxyz | 4 | 8 | 7 |... 

我需要的輸出在不同的文件作爲

文件1:

Code | Name | Day1 

10001 | abcd | 5 
10002 | degg | 3 
10003 | gxyz | 4 

文件2:

Code | Name | Day2 

10001 | abcd | 1 
10002 | degg | 9 
10003 | gxyz | 8 

文件3:

Code | Name | Day3 

10001 | abcd | 9 
10002 | degg | 6 
10003 | gxyz | 7 

等等....

我寫了這樣的

awk 'BEGIN { FS = "\t" } ; {print $1,$2,$3}' FILE_NAME > file1; 
awk 'BEGIN { FS = "\t" } ; {print $1,$2,$4}' FILE_NAME > file2; 
awk 'BEGIN { FS = "\t" } ; {print $1,$2,$5}' FILE_NAME > file3; 

等代碼...

現在我需要寫在'for'或'while'循環中,這會更快...

我不知道確切的代碼,可能是這樣的..

for ((i=3; i<=NF; i++)) ; do awk 'BEGIN { FS = "\t" } ; {print $1,$2,$i}' input.tsv > $i.tsv; done 

好心幫我得到的輸出作爲我解釋。

+0

你混合殼和awk。 ..單獨使用awk .. https://www.gnu.org/software/gawk/manual/html_node/For-Statement.html – Sundeep

+0

對不起,我不知道區分awk和shell。如果可能,請直接告訴我代碼以獲取該輸出。 @Sundeep –

+0

看看早先評論中的文檔鏈接的語法...你只需要將其移動到awk中的循環中...試試看吧 – Sundeep

回答

2

如果絕對需要猛砸來使用一個循環,那麼你的循環可以固定這樣的:

for ((i = 3; i <= 10; i++)); do awk -v field=$i 'BEGIN { FS = "\t" } { print $1, $2, $field }' input.tsv > file$i.tsv; done 

但它會真的更好解決這個問題,使用純awk,根本沒有外殼:

awk -v FS='\t' ' 
    NR == 1 { 
    for (i = 3; i < NF; i++) { 
     fn = "file" (i - 2) ".txt"; 
     print $1, $2, $i > fn; 
     print "" >> fn; 
    } 
    } 
    NR > 2 { 
    for (i = 3; i < NF; i++) { 
     fn = "file" (i - 2) ".txt"; 
     print $1, $2, $i >> fn; 
    } 
    }' inputfile 

也就是說,當你在第一個記錄, 寫標題行和空行(如在你的問題中指定)創建輸出文件。

對於第3個及以後的記錄,附加到文件。

請注意,您的問題中的代碼表明該文件中的字段由製表符分隔,但示例文件似乎使用填充了可變數量空格的|。目前還不清楚哪一個是你的實際案例。如果它真的是製表符分隔的,那麼上面的代碼就可以工作。如果實際上它是作爲例子輸入,則第一行改成這樣:

awk -v OFS=' | ' -v FS='[ |]+' ' 
+0

Hi Janos,你可以給你的郵件ID。我想向你展示我的原始需求。 @janos –

+2

嗨@ArunVenkitusamy,我寧願不。如果您的真實需求與您的問題不同,那是非常不幸的,我希望您先寫下。問問題,得到答案,然後將問題改爲其他問題是不公平的。如果需要稍作澄清,請編輯您的問題,也許我們可以提供幫助。如果你需要不同的東西,最好問一個新問題。 – janos

+0

嗨@janos,對不起,浪費你的時間..我創造了一個新的問題。請看看[http://stackoverflow.com/questions/43965359/awk-or-shell-script-to-change-format-of-a-tab-delimited-file] –

2

的bash + 溶液:

input.tsv試驗內容:

Code | Name | Day1 | Day2 | Day3 
10001 | abcd | 5 | 1 | 9 
10002 | degg | 3 | 9 | 6 
10003 | gxyz | 4 | 8 | 7 

day_splitter。SH腳本:

#!/bin/bash 

n=$(cat $1 | head -1 | awk -F'|' '{print NF}') # total number of fields 
for ((i=3; i<=$n; i++)) 
do 
    fn="Day"$(($i-2)) # file name containing `Day` number 
    $(cut -d'|' -f1,2,$i $1 > $fn".txt") 
done 

用法

bash day_splitter.sh input.tsv 

結果

$cat Day1.txt 
Code | Name | Day1 
10001 | abcd | 5 
10002 | degg | 3 
10003 | gxyz | 4 

$cat Day2.txt 
Code | Name | Day2 
10001 | abcd | 1 
10002 | degg | 9 
10003 | gxyz | 8 

$cat Day3.txt 
Code | Name | Day3 
10001 | abcd | 9 
10002 | degg | 6 
10003 | gxyz | 7 
0

在純AWK:

$ awk 'BEGIN{FS=OFS="|"}{for(i=3;i<=NF;i++) {f="file" (i-2); print $1,$2,$i >> f; close(f)}}' file 

解釋:

$ awk ' 
BEGIN { 
    FS=OFS="|" }    # set delimiters 
{ 
    for(i=3;i<=NF;i++) {  # loop the consumption fields 
     f="file" (i-2)  # create the filename 
     print $1,$2,$i >> f # append to target file 
     close(f) }   # close the target file 
}' file