Bash 获取n条最后记录并更改其中的特定列

Bash 获取n条最后记录并更改其中的特定列,bash,awk,Bash,Awk,我有这样的文件 1 2 "45554323" p b 2 2 "34534567" f a 3 3 "76546787" u b 2 4 "56765435" f a * a 0 b 我想从END{}部分的最后两条记录中删除a,b 结果: 1 2 "45554323"

我有这样的文件

1      2      "45554323"      p      b  
2      2      "34534567"      f      a  
3      3      "76546787"      u      b  
2      4      "56765435"      f      a  
*      a  
0      b  
我想从
END{}
部分的最后两条记录中删除
a
b

结果:

1      2      "45554323"      p      b  
2      2      "34534567"      f      a  
3      3      "76546787"      u      b  
2      4      "56765435"      f      a  
*        
0        

如何使用awk获取n个最后一行并更改其上的字段?

这并不能完全回答您的问题,但它会生成您需要的输出:

$ gawk '{if (NF < 3) print $1; else print}' input.txt
1      2      "45554323"      p      b
2      2      "34534567"      f      a
3      3      "76546787"      u      b
2      4      "56765435"      f      a
*
0
$gawk'{if(NF<3)print$1;else print}'input.txt
1 2“45554323”磅
2 2“34567”f a
3 3英寸76546787英寸英制
2 4“56765435”f a
*
0

这并不能完全回答您的问题,但它会产生您需要的输出:

$ gawk '{if (NF < 3) print $1; else print}' input.txt
1      2      "45554323"      p      b
2      2      "34534567"      f      a
3      3      "76546787"      u      b
2      4      "56765435"      f      a
*
0
$gawk'{if(NF<3)print$1;else print}'input.txt
1 2“45554323”磅
2 2“34567”f a
3 3英寸76546787英寸英制
2 4“56765435”f a
*
0

如果您知道
n
的值-您想删除行/column上最后一项的行号(此处为
4
),这将起作用:

awk '{if (NR>4) NF=NF-1}1' data.txt
将提供:

1      2      "45554323"      p      b  
2      2      "34534567"      f      a  
3      3      "76546787"      u      b  
2      4      "56765435"      f      a  
*
0
NF=NF-1
使awk认为行上的字段比实际少一个,这就是在满足该条件后,它不会显示行上的最后一列/项目的原因
NR
指正在读取的文件中的当前行号


awk无法知道文件中的行数,除非它经过一次,或者得到该信息(例如,
wc-l
)。另一种方法是将最后的
n
行保存在缓冲区中(类似于滑动窗口/磁带延迟类型,您总是在后面打印
n
行)然后在
END
块中处理最后的
n
行。

如果您知道
n
的值-行号,在此之后您要删除行/列上的最后一项(此处
4
),这将起作用:

awk '{if (NR>4) NF=NF-1}1' data.txt
$ cat file
1      2      "45554323"      p      b
2      2      "34534567"      f      a
3      3      "76546787"      u      b
2      4      "56765435"      f      a
*      a
0      b

$ awk 'BEGIN{ARGV[ARGC++]=ARGV[ARGC-1]} NR==FNR{nr++; next} FNR>(nr-2) {NF--} 1' file
1      2      "45554323"      p      b
2      2      "34534567"      f      a
3      3      "76546787"      u      b
2      4      "56765435"      f      a
*
0
将提供:

1      2      "45554323"      p      b  
2      2      "34534567"      f      a  
3      3      "76546787"      u      b  
2      4      "56765435"      f      a  
*
0
NF=NF-1
使awk认为行上的字段比实际少一个,这就是在满足该条件后,它不会显示行上的最后一列/项目的原因
NR
指正在读取的文件中的当前行号

awk无法知道文件中的行数,除非它经过一次,或者得到该信息(例如,
wc-l
)。另一种方法是将最后的
n
行保存在缓冲区中(类似于滑动窗口/磁带延迟类型,您总是在后面打印
n
行),然后在
END
块中处理最后的
n

$ cat file
1      2      "45554323"      p      b
2      2      "34534567"      f      a
3      3      "76546787"      u      b
2      4      "56765435"      f      a
*      a
0      b

$ awk 'BEGIN{ARGV[ARGC++]=ARGV[ARGC-1]} NR==FNR{nr++; next} FNR>(nr-2) {NF--} 1' file
1      2      "45554323"      p      b
2      2      "34534567"      f      a
3      3      "76546787"      u      b
2      4      "56765435"      f      a
*
0
或者,如果不介意手动指定两次文件名:

awk 'NR==FNR{nr++; next} FNR>(nr-2) {NF--} 1' file file
或者,如果不介意手动指定两次文件名:

awk 'NR==FNR{nr++; next} FNR>(nr-2) {NF--} 1' file file

这里有一种使用GNU awk的方法:

awk -v count=$(wc -l <file.txt) 'NR > count - 2 { $2 = "" }1' file.txt
或者,若要对所有记录执行
awk
操作(作为shell脚本的输入文件的最后两行除外),请尝试
/script.sh file.txt
script.sh的内容

command=$(awk -v count=$(wc -l <"$1") 'NR <= count - 2 { $2 = "" }1' "$1"
echo -e "$command"

这里有一种使用GNU awk的方法:

awk -v count=$(wc -l <file.txt) 'NR > count - 2 { $2 = "" }1' file.txt
或者,若要对所有记录执行
awk
操作(作为shell脚本的输入文件的最后两行除外),请尝试
/script.sh file.txt
script.sh的内容

command=$(awk -v count=$(wc -l <"$1") 'NR <= count - 2 { $2 = "" }1' "$1"
echo -e "$command"

@levon..记录数是可变的,因为我的文件是其他awk操作的结果,并且我的最后两行在此操作中发生了更改,但我希望删除在最后两行中创建的新列records@mohammadreshad如果您知道文件中的行数(来自上一次操作)然后,您应该能够将条件更改为
if(NO\u OF_LINE-2>NR)
或类似于这些行的内容。awk将无法知道行数,除非它遍历该文件一次,或者您向其提供该信息。也许
sed
可以更容易地做到这一点。@levon..记录的数量是可变的,因为我的文件是其他awk操作的结果,并且我的最后两行在此操作中发生了更改,但我希望删除最后两行中创建的新列records@mohammadreshad如果您知道文件中的行数(来自上一次操作)然后,您应该能够将条件更改为
if(NO\u OF_LINE-2>NR)
或类似于这些行的内容。awk将无法知道行数,除非它遍历该文件一次,或者您向其提供该信息。也许
sed
可以更容易地做到这一点。