20.33 如何将一个文本文件倒序输出 https://scz.617.cn/unix/201512241740.txt Q: 如何将bar文件内容倒序输出? $ cat bar 1 c 3 e 5 a 4 d 2 b A: 据说有个tac命令(就是cat反过来写),不过很多系统没有tac可用。一般来说,可以 用sed实现: $ sed '1!G;h;$!d' bar 2 b 4 d 5 a 3 e 1 c D: scz 2015-12-24 17:40 参看sed(1)。 sed逐行处理文本。每读取一行,存到pattern space中;针对pattern space进行处 理,可能有一系列命令处理pattern space;处理完毕,显示pattern space中的内容; 读取下一行,重复整个过程直至文件结束。 除了pattern space,sed还提供了一个hold space,用于临时存储某些数据。 sed有一些操作pattern space、hold space的高级命令: n 读取下一行覆盖pattern space N 读取下一行append到pattern space\n后 g 用hold space中内容覆盖pattern space G 将hold space中内容append到pattern space\n后 h 用pattern space中内容覆盖hold space H 将pattern space中内容append到hold space\n后 d 删除pattern space中内容,新读取下一行到pattern space中 D 删除pattern space中多行内容的第一行,不新读取下一行 s/regexp/replacement/ 针对pattern space进行正则匹配 & replacement中可以使用&,引用pattern space中正则匹配命中的内容 下面解释'1!G;h;$!d': 1!G 对第一行不执行G命令,从第二行开始执行 h 用pattern space中内容覆盖hold space $!d 对最后一行不执行d命令 这下就可以理解为什么最终倒序输出整个文本文件。我想说,sed太NB。 处理到最后一行时,pattern space、hold space中实际保存了所有行,只不过是倒 序的。因此这个方案受制于pattern space、hold space的大小,如果待处理文本行 数过多,sed肯定会失败。 D: scz 2015-12-25 10:03 $ awk '{x[NR]=$0}END{for(i=NR;i>0;i--)print x[i]}' bar 2 b 4 d 5 a 3 e 1 c 这里的x[]相当于sed的hold space。FNR、NR从1开始计,不是从0开始。