awk:打印所有内容但不打印最后一列

时间:2014-11-04 21:43:52

标签: awk

我有一个这种形式的输入文件:

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
[...]

6 个答案:

答案 0 :(得分: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

答案 1 :(得分: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 :(得分: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

答案 3 :(得分: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

答案 4 :(得分:0)

这应该在最后三个之前的任意数量的字段中执行:

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

答案 5 :(得分:0)

我是awk的新手,但是这个怎么样(这不会删除空格。):

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

示例:

sdlcb@Goofy-Gen:~/AMD$ cat file
foo bar 08 320984 2384
bla foo baz 23 32425 32532

sdlcb@Goofy-Gen:~/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