如何在Linux中删除文件的最后一列

如何在Linux中删除文件的最后一列

我想删除txt文件的最后一列,但我不知道列号是多少。我怎么能这样做呢?

例子:

输入:

1223 1234 1323 ... 2222 123
1233 1234 1233 ... 3444 125
0000 5553 3455 ... 2334 222

我希望我的输出是:

1223 1234 1323 ... 2222
1233 1234 1233 ... 3444
0000 5553 3455 ... 2334

答案1

awk

awk 'NF{NF-=1};1' <in >out

或者:

awk 'NF{NF--};1' <in >out

或者:

awk 'NF{--NF};1' <in >out

虽然这看起来像巫术,但它确实有效。每个 awk 命令都包含三个部分。

第一个是NF,这是第二部分的前提。NF是一个变量,包含一行中的字段数。在 AWK 中,如果不是 0 或空字符串,则为 true ""。因此,第二部分(其中NF递减)仅在NF不为 0 时发生。

第二部分(NF-=1 NF----NF)只是从NF变量中减一。这会阻止打印最后一个字段,因为当您更改字段(在本例中删除最后一个字段)时,会awk重新构造$0,默认情况下连接所有以空格分隔的字段。$0不再包含最后一个字段。

最后一部分是1。它并不神奇,它只是用作一个表示意思的表达方式true。如果awk表达式计算结果为 true 且没有任何关联操作,则awk默认操作为print $0

答案2

使用 Perl:

perl -lane '$,=" ";pop(@F);print(@F)' in

使用rev+ cut

rev in | cut -d ' ' -f 2- | rev

答案3

grep与 PCRE 一起使用:

$ grep -Po '.*(?=\s+[^\s]+$)' file.txt 
1223 1234 1323 ... 2222
1233 1234 1233 ... 3444
0000 5553 3455 ... 2334

使用 GNU sed

$ sed -r 's/(.*)\s+[^\s]+$/\1/' file.txt 
1223 1234 1323 ... 2222
1233 1234 1233 ... 3444
0000 5553 3455 ... 2334

答案4

如果分隔符始终是单个字符(因此两个或多个连续分隔符指定空字段),您可以head仅从输入文件的第一行计算分隔符(n分隔符意味着字段数n+1),然后使用从st 字段cut打印1直到n第一个字段(倒数第二个),例如使用制表符分隔的输入:

n=$(head -n 1 infile | tr -dc \\t | tr \\t \\n | wc -l)
cut -f1-$n infile > outfile

或者例如用数据集文件:

n=$(head -n 1 infile | tr -dc , | tr , \\n | wc -l)
cut -d, -f1-$n infile > outfile

如果有时间,我稍后会运行一些基准测试,但输入量很大,我认为这个解决方案应该比使用正则表达式的其他解决方案更快,因为这个解决方案在第一行上进行了最少的处理以获得否。字段,然后使用cut针对该工作优化的字段。

相关内容