我想删除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
针对该工作优化的字段。