一个 awk 可以做到:
awk '{a[i++]=$0};/-----/{++j};j==3{t="";for(k=0;k<i;++k)t=t a[k]"\n";b[++l]=t;i=j=0}END{for(i=l;i;--i)printf "%s", b[i]}' file
输出:
----------------------------------------------------------------
date time hostname cpu ram / /opt
----------------------------------------------------------------
2013/09/08 15:40:00 server1 20% 30% 50% 70%
2013/09/08 15:40:00 server2 15% 21% 49% 72%
2013/09/08 15:40:00 server3 20% 40% 40% 75%
----------------------------------------------------------------
----------------------------------------------------------------
date time hostname cpu ram / /opt
----------------------------------------------------------------
2013/09/08 15:35:00 server1 15% 30% 50% 70%
2013/09/08 15:35:00 server2 18% 21% 49% 72%
2013/09/08 15:35:00 server3 15% 40% 40% 75%
----------------------------------------------------------------
----------------------------------------------------------------
date time hostname cpu ram / /opt
----------------------------------------------------------------
2013/09/08 15:30:00 server1 20% 30% 50% 70%
2013/09/08 15:30:00 server2 10% 21% 49% 72%
2013/09/08 15:30:00 server3 15% 40% 40% 75%
----------------------------------------------------------------
另一个可以排除无效数据的更安全的变体:
awk '/^-----+$/{++j};!j{next};{a[i++]=$0}j==3{t="";for(k=0;k<i;++k)t=t a[k]"\n";b[++l]=t;i=j=0}END{for(i=l;i;--i)printf "%s", b[i]}' file
另一个基于行数的:
awk '{a[i++]=$0}i==7{t="";for(k=0;k<i;++k)t=t a[k]"\n";b[++l]=t;i=0}END{for(i=l;i;--i)printf "%s", b[i]}' file
简单一点:
awk '{a[i++]=$0}i==7{t="";for(i=0;i<7;++i)t=t a[i]"\n";b[++j]=t;i=0}END{for(;j;--j)printf "%s", b[j]}' file
另一种在 Bash 中使用相同概念的简单方法:
( IFS=$'\n'; while read -r A[I++]; do [[ I -eq 7 ]] && { B[++J]="${A[*]}"; I=0; }; done; for ((;J;--J)); do echo "${B[J]}"; done; ) < file
Ruby 的另一个真正的单行代码:
ruby -e '$stdin.readlines().each_slice(7).entries.reverse.each { |b| puts b; }' < file