请考虑以下命令:
gawk -F"\t" "BEGIN{OFS=\"\t\"}{$2=$3=\"\"; print $0}" Input.tsv
当我设置$ 2 = $ 3 =“”时,获得与写入相同效果的预期效果:
print $1,$4,$5...$NF
然而,实际发生的是我得到两个空字段,额外的字段分隔符仍在打印。
是否可以实际删除$ 2和$ 3?
注意:如果这是在Linux上 bash
,上面的正确陈述如下,但Windows不能很好地处理单引号 cmd.exe
。
gawk -F'\t' 'BEGIN{OFS="\t"}{$2=$3=""; print $0}' Input.tsv
这是一个老人,但好。
正如Jonathan指出的那样,你不能删除中间的字段,但可以用其他字段的内容替换它们的内容。并且您可以创建一个可重用的函数来为您处理删除。
$ cat test.awk
function rmcol(col, i) {
for (i=col; i<NF; i++) {
$i=$(i+1)
}
NF--
}
{
rmcol(3)
}
1
$ printf 'one two three four\ntest red green blue\n' | awk -f test.awk
one two four
test red blue
您不能删除中间的字段,但可以通过递减删除最后的字段 NF
。
因此,您可以将所有后面的字段向下移动以覆盖 $2
和 $3
然后减少 NF
两个,删除最后两个字段:
$ echo 1 2 3 4 5 6 7 | awk '{for(i=2; i<NF-1; ++i) $i=$(i+2); NF-=2; print $0}'
1 4 5 6 7
如果您只想删除列,则可以使用 cut
:
cut -f 1,4- file.txt
要模仿 cut
:
awk -F "\t" '{ for (i=1; i<=NF; i++) if (i != 2 && i != 3) { if (i == NF) printf $i"\n"; else printf $i"\t" } }' file.txt
类似:
awk -F "\t" '{ delim =""; for (i=1; i<=NF; i++) if (i != 2 && i != 3) { printf delim $i; delim = "\t"; } printf "\n" }' file.txt
HTH
一种方法是删除像你一样的字段,并删除多余的空格 gsub
:
awk 'BEGIN { FS = "\t" } { $2 = $3 = ""; gsub( /\s+/, "\t" ); print }' input-file
在自杀史蒂夫的回答中,我想建议一个更多的解决方案,但使用sed而不是awk。
这似乎比史蒂夫建议的切割使用更复杂。但这是更好的解决方案,因为sed -i允许就地编辑。
sed -i 's/\(.*,\).*,.*,\(.*\)/\1\2/' FILENAME
我可以想到在不使用循环的情况下在Awk中执行此操作的唯一方法是使用 gsub
上 $0
结合相邻 FS
:
$ echo {1..10} | awk '{$2=$3=""; gsub(FS"+",FS); print}'
1 4 5 6 7 8 9 10
好吧,如果目标是删除额外的分隔符,那么你可以在Linux上使用“tr”。例:
$ echo“1,2 ,,, 5”| tr -s','
1,2,5
echo one two three four five six|awk '{
print $0
is3=$3
$3=""
print $0
print is3
}'
一二三四五六
一二四五六
三