2014-11-04 54 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