如何使用 awk 命令仅编辑最后一行(或任何特定行号)?

Dan*_*iel 1 linux awk text-processing gawk

我有一个大的多列文件,其中包含 #n 条记录(行)。我如何只能awk在最后一条记录或任何特定记录号(ig NR==4)或一系列行(NR==[2-5])中应用命令?

作为以下文件中的示例:

echo filename
30.5,2010/06/01,2016/08/29,2281.00,0006.25,0074.94
41.6,2008/03/05,2012/03/05,1461.00,0004.00,0048.00
39.6,2008/03/05,2012/09/10,1649.96,0004.52,0054.21
41.0,2008/03/05,2013/09/16,2020.96,0005.53,0066.40
42.2,2008/03/05,2014/03/18,2203.96,0006.03,0072.41
41.1,2008/03/05,2014/09/16,2385.96,0006.53,0078.39
43.1,2008/05/08,2014/09/16,/2322.00,/0006.36,/0076.29
Run Code Online (Sandbox Code Playgroud)

我应用以下 awk 脚本来删除/除日期以外的任何字段中的 。

nawk -F, -v OFS=,  '{split($4,a,"/"); $4=sprintf("%06.2f", a[2]);split ($5,b,"/");$5=sprintf("%06.2f", b[2]);split($6,c,"/");$6=sprintf("%06.2f", c[2]); print $0}' filename 
Run Code Online (Sandbox Code Playgroud)

虽然最后一行是正确的,但对其他没有/. 以下输出:

output

30.5,2010/06/01,2016/08/29,000.00,000.00,000.00
41.6,2008/03/05,2012/03/05,000.00,000.00,000.00
39.6,2008/03/05,2012/09/10,000.00,000.00,000.00
41.0,2008/03/05,2013/09/16,000.00,000.00,000.00
42.2,2008/03/05,2014/03/18,000.00,000.00,000.00
41.1,2008/03/05,2014/09/16,000.00,000.00,000.00
43.1,2008/05/08,2014/09/16,2322.00,006.36,076.29


however, the expected correct output should be :

30.5,2010/06/01,2016/08/29,2281.00,0006.25,0074.94
41.6,2008/03/05,2012/03/05,1461.00,0004.00,0048.00
39.6,2008/03/05,2012/09/10,1649.96,0004.52,0054.21
41.0,2008/03/05,2013/09/16,2020.96,0005.53,0066.40
42.2,2008/03/05,2014/03/18,2203.96,0006.03,0072.41
41.1,2008/03/05,2014/09/16,2385.96,0006.53,0078.39
43.1,2008/05/08,2014/09/16,2322.00,0006.36,0076.29
Run Code Online (Sandbox Code Playgroud)

那么,我如何告诉 awk 仅在最后一行或任何特定行号中应用它?

Tho*_*key 5

当 awk 处理文件时,该变量NR表示处理的记录总数。所以你只需要添加一个模式,比如

(NR == 5)
Run Code Online (Sandbox Code Playgroud)

在你行动之前

{split($4,a,"/");...
Run Code Online (Sandbox Code Playgroud)

例如,

(NR == 5){split($4,a,"/");...
Run Code Online (Sandbox Code Playgroud)

处理第 5 行。

如果您只想处理最后一行,那么您可以在默认操作中保存该行

{ save = $0; }
Run Code Online (Sandbox Code Playgroud)

并在该END部分中处理该行。但是您必须在那里进行字段拆分($0不再适用):

END {split(whatever,a,"/");...
Run Code Online (Sandbox Code Playgroud)

对于范围,您将使用更复杂的表达式,

( NR >= 2 && NR <= 5 )
Run Code Online (Sandbox Code Playgroud)

选择第 2 行到第 5 行。

进一步阅读: