awk:打印所有内容,但不打印最后的第n列
我有一个这样的输入文件:awk:打印所有内容,但不打印最后的第n列,awk,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 [...] 如果我正确理解你和fedorqu
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
[...]
如果我正确理解你和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
awk'{for(i=1;iNF?”;“:FS);打印$NF}”文件
富吧;08;320984;2384
布拉富巴兹;23;32425;32532
这将添加代码>位于最后三个字段前面
可能是更好的方法。如果我正确理解你和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
awk'{for(i=1;iNF?”;“:FS);打印$NF}”文件
富吧;08;320984;2384
布拉富巴兹;23;32425;32532
这将添加代码>位于最后三个字段前面
这可能是更好的方法。不幸的是,awk并不是最擅长的(而且cut
的字段范围处理能力在这里也没有帮助
不过,类似的方法应该可以奏效:
awk '{nfff=$(NF-2); nff=$(NF-1); nf=$NF; NF-=3; printf "%s;%s;%s;%s\n", $0, nfff, nff, nf}' file
不幸的是,awk并不是最好的(而且cut
的字段范围处理能力在这里也没有帮助
不过,类似的方法应该可以奏效:
awk '{nfff=$(NF-2); nff=$(NF-1); nf=$NF; NF-=3; printf "%s;%s;%s;%s\n", $0, nfff, nff, nf}' file
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
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
一种奇特的GNU awk方法:
gawk '
function replace(what) {
return gensub(/[[:blank:]]+([^[:blank:]]+)$/, ";\\1", 1, what)
}
{$0 = replace(replace(replace($0))); print}
' file
一种奇特的GNU awk方法:
gawk '
function replace(what) {
return gensub(/[[:blank:]]+([^[:blank:]]+)$/, ";\\1", 1, what)
}
{$0 = replace(replace(replace($0))); print}
' file
对于最后三个字段之前的任意数量的字段,应执行此操作:
awk '{for (i=1; i <= NF - 3; i++) if (i == 1) printf $i; else printf " "$i} {print ";"$(NF-2)";"$(NF-1)";"$NF}' input
awk'{for(i=1;i这应该适用于最后三个字段之前的任意数量的字段:
awk '{for (i=1; i <= NF - 3; i++) if (i == 1) printf $i; else printf " "$i} {print ";"$(NF-2)";"$(NF-1)";"$NF}' input
<代码> AWK { for(i=1;i)我对AWK是新的,但这如何(这不会删除空白空间):< /P>
<代码> AWK { for(i=0;i)我对AWK是新的,但这如何(这不会删除空白空间):< /P>
awk'{for(i=0;这不是CSV
,但这不是重点。您正在尝试将文件拆分为四个输出字段?其中最后三个字段是输入的最后三个字段,第一个字段是行中的所有其他字段?您如何知道什么是标记?任何没有数字的文本?一行中有两个单词,一行中有三个单词“最后总是有三个记号,但前面的记号数目不详”这句话的大意是我知道它总是像tk1 tk2 tk3…tkn tk1 tk2 tk3
一样,必须变成tk1 tk2 tk3…tkn;tk1;tk2;tk3
@fedorqui所以简而言之,为最后三个字段中的每一个添加;
。@Jotne在前面,准确地说。这不是CSV
,但这不是重点。你正试图将文件拆分为到四个输出字段?其中最后三个字段是输入的最后三个字段,第一个字段是行中的所有其他字段?您如何知道什么是标记?任何没有数字的文本?一行有两个单词,另一行有三个单词。@Jotne“最后总是有三个代币,但前面的代币数量未知“我知道它总是像tk1 tk2 tk3…tkn tk1 tk2 tk3
,必须变成tk1 tk2 tk3…tkn;tk1;tk2;tk3
@fedorqui所以简而言之,为最后三个字段中的每一个添加;
。@Jotne在前面。方法上的一个小变化:$awk'{last=“;”;“$(NF-2)”;“$(NF-1)”;”$NF;NF-=3;print$0 last}'文件
方法上的一个小变化:$awk'{last=“;”$(NF-2)”;“$(NF-1)”;“$NF;NF-=3;print$0 last}”文件