awk - 打印排序文件的最后一组
awk - print the last group from a sorted file
我想打印以下文件中的最后一组,第一个字段作为键。
输入:
62,2010-06-19,27.40
62,2010-06-20,35.40
62,2010-06-21,8.50
63,2010-06-19,56.40
63,2010-06-20,23.76
63,2010-06-21,12.50
63,2010-06-22,87.12
64,2010-06-19,87.40
64,2010-06-20,32.40
64,2010-06-21,21.50
64,2010-06-22,73.40
所需输出:
64,2010-06-19,87.40
64,2010-06-20,32.40
64,2010-06-21,21.50
64,2010-06-22,73.40
我试过
awk -F, ' { p=NR==1?:p; a[NR]=[=12=] } p!= { delete a; p= } END { for(i in a) print a[i] } '
但是少了一行。
最有效(和简短)的方法是:
$ tac file | awk -F',' '(NR>1) && (!=p){exit} {print; p=}' | tac
64,2010-06-19,87.40
64,2010-06-20,32.40
64,2010-06-21,21.50
64,2010-06-22,73.40
或者如果你没有 tac:
$ awk -F',' '!=p{rec=""; p=} {rec=rec [=11=] ORS} END{printf "%s", rec}' file
64,2010-06-19,87.40
64,2010-06-20,32.40
64,2010-06-21,21.50
64,2010-06-22,73.40
或者如果出于某种原因您更喜欢将最后一条记录存储在数组中而不是字符串中:
$ awk -F',' '!=p{n=0; p=} {rec[++n]=[=12=]} END{for (i=1; i<=n; i++) print rec[i]}' file
64,2010-06-19,87.40
64,2010-06-20,32.40
64,2010-06-21,21.50
64,2010-06-22,73.40
仅供参考,脚本中的 for(i in a)
会打乱行的顺序,因此输出顺序与输入顺序不同(除非巧合)。
此外,关于 p=NR==1?:p
- 如果您将三元表达式括在括号中,它们总是更易于阅读,并且在某些上下文中,当您不这样做时,它们可能会导致某些 awks 中的语法错误,所以总是将它们括起来,例如p=(NR==1?:p)
.
另一种 tac + awk + tac
不使用数组的解决方案:
tac file | awk -F, 'p && != p{exit} {p = } 1' | tac
64,2010-06-19,87.40
64,2010-06-20,32.40
64,2010-06-21,21.50
64,2010-06-22,73.40
我想打印以下文件中的最后一组,第一个字段作为键。
输入:
62,2010-06-19,27.40
62,2010-06-20,35.40
62,2010-06-21,8.50
63,2010-06-19,56.40
63,2010-06-20,23.76
63,2010-06-21,12.50
63,2010-06-22,87.12
64,2010-06-19,87.40
64,2010-06-20,32.40
64,2010-06-21,21.50
64,2010-06-22,73.40
所需输出:
64,2010-06-19,87.40
64,2010-06-20,32.40
64,2010-06-21,21.50
64,2010-06-22,73.40
我试过
awk -F, ' { p=NR==1?:p; a[NR]=[=12=] } p!= { delete a; p= } END { for(i in a) print a[i] } '
但是少了一行。
最有效(和简短)的方法是:
$ tac file | awk -F',' '(NR>1) && (!=p){exit} {print; p=}' | tac
64,2010-06-19,87.40
64,2010-06-20,32.40
64,2010-06-21,21.50
64,2010-06-22,73.40
或者如果你没有 tac:
$ awk -F',' '!=p{rec=""; p=} {rec=rec [=11=] ORS} END{printf "%s", rec}' file
64,2010-06-19,87.40
64,2010-06-20,32.40
64,2010-06-21,21.50
64,2010-06-22,73.40
或者如果出于某种原因您更喜欢将最后一条记录存储在数组中而不是字符串中:
$ awk -F',' '!=p{n=0; p=} {rec[++n]=[=12=]} END{for (i=1; i<=n; i++) print rec[i]}' file
64,2010-06-19,87.40
64,2010-06-20,32.40
64,2010-06-21,21.50
64,2010-06-22,73.40
仅供参考,脚本中的 for(i in a)
会打乱行的顺序,因此输出顺序与输入顺序不同(除非巧合)。
此外,关于 p=NR==1?:p
- 如果您将三元表达式括在括号中,它们总是更易于阅读,并且在某些上下文中,当您不这样做时,它们可能会导致某些 awks 中的语法错误,所以总是将它们括起来,例如p=(NR==1?:p)
.
另一种 tac + awk + tac
不使用数组的解决方案:
tac file | awk -F, 'p && != p{exit} {p = } 1' | tac
64,2010-06-19,87.40
64,2010-06-20,32.40
64,2010-06-21,21.50
64,2010-06-22,73.40