2016-08-05 58 views
0

我有一個input.csv文件,第2列和第3列中有變量lengtt。如何使用awk或sed調整bash中的列字段的長度?

100,Short Column, 199 
200,Meeedium Column,1254 
300,Loooooooooooong Column,35 

我嘗試使用下面的命令來實現一個乾淨的列表,但我需要填充一定數量的空格的第2列,以獲得一個固定的lenght柱(比方說,一個總長度爲30就足夠了)。

awk -F, '{print $1 "\t" $2 "\t" $3;}' input.csv 

我的電流輸出是這樣的:

100 Short Column 199 
200 Meeedium Column 1254 
300 Loooooooooooong Column 35 

而且我想實現下面的輸出,通過填充第二,妥善第3列:

100 Short Column    199 
200 Meeedium Column   1254 
300 Loooooooooooong Column  35 

什麼好主意了那裏應該使用awk或sed命令? 謝謝大家。

+3

'列-t input.csv'或看看'printf'或'awk'的' printf'。 – Cyrus

+0

'列-s,-t文件'應該這樣做 – anubhava

+1

@anubhava:謝謝。 – Cyrus

回答

1

而不是採摘一些任意數作爲每個字段的寬度的解決方案,因爲,那裏的第一遍計算每個字段的最大長度和第二打印的字段的2步方法在尺寸加場之間的耦合的空格的寬度:

$ cat tst.awk 
BEGIN { FS=" *, *"; OFS=" " } 
NR==FNR { 
    for (i=1;i<=NF;i++) { 
     w[i] = (length($i) > w[i] ? length($i) : w[i]) 
     if ($i ~ /[^0-9]/) { 
      a[i] = "-" 
     } 
    } 
    next 
} 
{ 
    for (i=1;i<=NF;i++) { 
     printf "%"a[i]w[i]"s%s", $i, (i<NF ? OFS : ORS) 
    } 
} 

$ awk -f tst.awk file file 
100 Short Column    199 
200 Meeedium Column   1254 
300 Loooooooooooong Column 35 

上面還使用左對準用於非數字字段,對於所有的位數字段右對齊。它會工作,不管輸入字段有多長,也不管你有多少領域有:

$ cat file1 
100000,Short Column, 199,a 
100,Now is the Winter of our discontent with fixed width fields,20000,b 
100,Short Column, 199,c 
200,Meeedium Column,1254,d 
300,Loooooooooooong Column,35,e 

$ awk -f tst.awk file1 file1 
100000 Short Column             199 a 
    100 Now is the Winter of our discontent with fixed width fields 20000 b 
    100 Short Column             199 c 
    200 Meeedium Column            1254 d 
    300 Loooooooooooong Column           35 e 
+1

輝煌的解決方案。是否有任何方法可以自定義tst.awk(或bash中的命令行)以便開始僅針對某些特定列進行對齊?例如:在包含30列的csv中,我希望僅將對齊應用於第20,21,22列(因爲從1到19的列僅僅是我希望從打印中丟棄的標題)。 –

+0

當然,只需將'1'更改爲您的起始字段編號和'NF'即可。如果你喜歡,用'-v'設置變量來傳入這些開始/結束值。如果你無法弄清楚,試試它併發佈一個新的跟進問題。如果您發佈了這個問題的答案,請記住通過點擊旁邊的複選標記來接受您選擇的那個(請參閱http://stackoverflow.com/help/someone-answers)。 –

+0

感謝您的提示,劇本完美無缺!我想知道是否有任何方法可以修改tst.awk腳本,以便爲數字字段進行正確對齊,也可以在小數點的情況下使用。目前,腳本在右側對齊數量1000,但左側數量爲1000.99(實際上這是我的錯誤,我沒有在我的問題中指定數字字段包含小數)。可能我應該添加一些代碼到你的行開始以下:if($ i〜/ [^ 0-9] /)。再次感謝你,一些代碼! –

2

使用printfawk

$ awk -F, '{gsub(/ /, "", $3); printf "%-5s %-25s%5s\n", $1, $2, $3}' file input.csv 
100 Short Column    199 
200 Meeedium Column   1254 
300 Loooooooooooong Column  35 

我在上面所做的,設置了IFS,字段分隔符,;由於該文件在第三列中僅有一些空格,因此它會損壞,printf如何處理字符串,如何使用gsub將其刪除,並使用C風格printf進行格式化。

+1

或用bash的printf:'while IFS =,read -r a b c;做printf「%5s%-25s%5s \ n」「$ a」「$ b」「$ c」;完成 Cyrus

+0

@Inian好的代碼!謝謝。是否有任何方法可以自定義awk以便開始僅針對某些特定列進行對齊?例如:在一個有30列的csv中,我希望僅將對齊方式應用於第20,21,22列(因爲第1至19列和第23至30列僅僅是我希望從打印中丟棄的頁眉/頁腳)。 –

0

使用perl

$ perl -pe 's/([^,]+),([^,]+),([^,]+)/sprintf "%-6s%-30s%5s", $1,$2,$3/e' input.csv 
100 Short Column     199 
200 Meeedium Column    1254 
300 Loooooooooooong Column   35 
相關問題