2016-10-28 38 views
1

編輯 行數和製表符分隔值也是動態的,因爲它可以更改。所以它可能是1-5或1-10的佈局,但該地區只會列出一次。在動態更改文件中,在bash中有效轉置來自tab /新行分隔文件的輸出


我有在以下格式的文件:(@ TSV)

host1 host2 host3 
id1 id2 id3 
ip1 ip2 ip3 
name1 name2 name3 
role1 role2 role3 
region 

我也可以格式如文件:

host1 
host2 
host3 
id1 
id2 
id3 
ip1 
ip2 
ip3 
name1 
name2 
name3 
role1 
role2 
role3 
region 

我想編寫一個新的文件或修改此文件內聯,以便文件是這種格式:(tsv)

host1 id1 ip1 name1 role1 region 
host2 id2 ip2 name2 role2 region 
host3 id3 ip3 name3 role3 region 

我已經試過沒有成功使用awk,sed,for循環...我需要一些新的想法。

+0

爲什麼在您的輸入文件中只有一次區域?它是三次,你需要的最終輸出很容易獲得 – Sundeep

+0

它看起來像你想轉置。我認爲用Python/Pandas這樣的東西可以快速而簡單。也許嘗試一些這些想法? http://stackoverflow.com/questions/1729824/transpose-a-file-in-bash(我還沒有嘗試過。) –

+0

如果確實需要轉置,這將是https:// stackoverflow的重複。 com/questions/40067992/reorder-columns-using-awk – Sundeep

回答

0

您可以使用以下awk腳本:

# translate.awk 

NR==1 { 
    split($0,hosts) 
} 
NR==2 { 
    split($0,ids) 
} 
NR==3{ 
    split($0,ips) 
} 
NR==4{ 
    split($0,names) 
} 
NR==5{ 
    split($0,roles) 
} 
NR==6{ 
    region=$1 
} 

END{ 
    OFS="\t" 
    for(i in hosts) { 
     print hosts[i], ids[i], ips[i], names[i], roles[i], region 
    } 
} 

這樣稱呼它:

awk -f translate.awk input.file 
+0

我真的很喜歡這個,但是如果文件每次運行都會動態改變呢? 有時它可能有10個主機或3個主機以及相應的信息。 –

+0

您是否看到任何將腳本限制爲3個主機的內容? :)腳本可以處理不同數量的主機。檢查最後的循環 – hek2mgl

+0

啊...最後一個問題... 我怎麼能把裏面的一個bash腳本,他們不會有單獨的.awk文件? –

0

與列表格式的版本開始,如果你有沒有丟失數據,即「宗教」 3次,它會容易得多。

您可以在飛行中添加缺少的值,然後簡單地pr

$ awk '1; END{print;print}' file | pr -6ts 

host1 id1  ip1  name1 role1 region 
host2 id2  ip2  name2 role2 region 
host3 id3  ip3  name3 role3 region 

如果列數是已知的,只有最後一個值可能會丟失,您可以通過列數參數化

$ cols=6; awk -v cols=$cols '1; END{for(i=1;i<=(NR-cols)/(cols-1);i++) print}' file | 
    pr -${cols}ts 
+0

僅在主機數量爲3時纔有效 – hek2mgl

+0

只要添加缺失值並且有6列,它就可以用於未指定數量的行(主機)。 – karakfa

+0

應該怎麼辦?您完全打印該區域3次。 – hek2mgl

0

慣用awk的辦法調換行列:

$ cat tst.awk 
BEGIN { FS=OFS="\t" } 
{ 
    numCols = NR 
    numRows = (NF>numRows ? NF : numRows) 
    for (rowNr=1; rowNr<=NF; rowNr++) { 
     vals[rowNr,numCols] = $rowNr 
    } 
} 
END { 
    for (rowNr=1; rowNr<=numRows; rowNr++) { 
     for (colNr=1; colNr<=numCols; colNr++) { 
      val = ((rowNr,colNr) in vals ? vals[rowNr,colNr] : vals[1,colNr]) 
      printf "%s%s", val, (colNr<numCols ? OFS : ORS) 
     } 
    } 
} 

$ awk -f tst.awk file 
host1 id1  ip1  name1 role1 region 
host2 id2  ip2  name2 role2 region 
host3 id3  ip3  name3 role3 region 

以上是關於你的第一個輸入文件運行:

$ cat file 
host1 host2 host3 
id1  id2  id3 
ip1  ip2  ip3 
name1 name2 name3 
role1 role2 role3 
region 

注意的腳本,使您的輸入沒有提到任何值,也沒有多少行或列,你有,也沒有任何其他假設你輸入的內容文件除外,如果缺少值,則需要重複第一個。

相關問題