2014-11-04 90 views
1

我在這個形式的輸入文件:AWK:打印一切,但不是最後的第n列

foo bar 08 320984 2384 
bla foo baz 23 32425 32532 
[...] 

總有三個令牌到底,但在前面的令牌數量不詳。我想將文件重寫爲CSV,以便可以由其他應用程序自動分析。我目前的awk命令是:

awk '{ print $(NF-2)";"$(NF-1)";"$NF}' 

輸出應該是

foo bar;08;320984;2384 
bla foo baz;23;32425;32532 
[...] 
+0

這不是'CSV'但是這不是點。您正試圖將您的文件分成四個輸出字段?最後三個字段是輸入的最後三個字段,第一個字段是行中的其他所有字段? – 2014-11-04 21:46:21

+1

你怎麼知道什麼是標記?任何文字沒有數字?你在一行中有兩個單詞,在另一個單詞中有三個單詞。 – Jotne 2014-11-04 22:15:53

+0

@Jotne從句子中「最後總是有三個令牌,但前面有一個未知數的令牌」我明白它總是像'tk1 tk2 tk3 ...tkn TK1 TK2 TK3'並且必須變成'tk1 tk2 tk3 ... tkn; TK1; TK2; TK3'。 – fedorqui 2014-11-05 09:00:58

回答

1

如果我理解你正確fedorqui:

awk '{for (i=1;i<NF;i++) printf "%s%s",$i,(i+4>NF?";":FS);print $NF}' file 
foo bar;08;320984;2384 
bla foo baz;23;32425;32532 

這將在最後三場的前面加;

John's comment可能是更好的方法來做到這一點。

2

這是很不幸了awk只是不是最大的(和cut的辦場範圍在這裏或者不利於能力

這樣的事情應該工作,雖然東西:

awk '{nfff=$(NF-2); nff=$(NF-1); nf=$NF; NF-=3; printf "%s;%s;%s;%s\n", $0, nfff, nff, nf}' file 
+3

您的方法的一個小變化:'$ awk'{last =「;」$(NF-2)「;」$(NF-1)「;」$ NF; NF-= 3;打印$ 0最後}文件 – John1024 2014-11-04 22:04:01

1

sed也可以工作:

sed 's/\ \([^\ ]\+\)\ \([^\ ]\+\)\ \([^\ ]\+\)$/;\1;\2;\3/' file 

,或者如果您sed支持-r

sed -r 's/\ ([^\ ]+)\ ([^\ ]+)\ ([^\ ]+)$/;\1;\2;\3/' file 

它用;取代最後3條換行符。

還是有點容易

rev file | sed 's/\ /;/g; s/;/\ /g4' | rev 
1

看上GNU AWK方法:

gawk ' 
    function replace(what) { 
     return gensub(/[[:blank:]]+([^[:blank:]]+)$/, ";\\1", 1, what) 
    } 
    {$0 = replace(replace(replace($0))); print} 
' file 
foo bar;08;320984;2384 
bla foo baz;23;32425;32532 
0

這應該這樣做了場任意數量的最後三個前:

awk '{for (i=1; i <= NF - 3; i++) if (i == 1) printf $i; else printf " "$i} {print ";"$(NF-2)";"$(NF-1)";"$NF}' input 
0

我是新來的awk,但如何對這個(這將不會刪除空格,但。):

awk '{for (i=0; i<3; i++) {$(NF-i)=";" $(NF-i)} print $0} ' file 

例子:

[email protected]:~/AMD$ cat file 
foo bar 08 320984 2384 
bla foo baz 23 32425 32532 

[email protected]:~/AMD$ awk '{for (i=0; i<3; i++) {$(NF-i)=";" $(NF-i)} print $0} ' file 
foo bar ;08 ;320984 ;2384 
bla foo baz ;23 ;32425 ;32532