在linux bash中,反转文件行顺序,但对于块,每3行

在linux bash中,反转文件行顺序,但对于块,每3行,linux,bash,Linux,Bash,我想逆转一个文件,但在这个文件中,我有记录3行每 a1 a2 a3 ... x1 x2 x3 我想得到这样的文件 x1 x2 x3 ... a1 a2 a3 我使用Linux,所以tail-r对我不起作用。这太难看了,我甚至有点不好意思发布它。。。所以我想我会在一个更合适的答案出现时删除它 tac /path/to/file | awk '{ a[(NR-1)%3]=$0; if (NR%3==0) { print a[2] "\n" a[1] "\n" a[0] }}' 使用该文件: ~

我想逆转一个文件,但在这个文件中,我有记录3行每

a1
a2
a3
...
x1
x2
x3
我想得到这样的文件

x1
x2
x3
...
a1
a2
a3

我使用Linux,所以tail-r对我不起作用。

这太难看了,我甚至有点不好意思发布它。。。所以我想我会在一个更合适的答案出现时删除它

tac /path/to/file | awk '{ a[(NR-1)%3]=$0; if (NR%3==0) { print a[2] "\n" a[1] "\n" a[0] }}'
使用该文件:

~$ cat f
1
2
3
4
5
6
7
8
9
使用awk:将第一行存储在a中,然后将每一行附加到a的顶部,对于第三行打印/重新初始化:

~$ awk '{a=$0"\n"a}NR%3==0{print a}NR%3==1{a=$0}' f
3
2
1
6
5
4
9
8
7
然后使用tac再次反转:

~$ awk '{a=$0"\n"a}NR%3==0{print a}NR%3==1{a=$0}' f | tac
7
8
9
4
5
6
1
2
3

您可以使用关联数组在awk中完成这一切:

BEGIN { j=1 }
++i>3 { i=1; ++j }
{ a[j,i]=$0 }
END{ for(m=j;m>0;--m)
       for(n=1;n<=3;++n) print a[m,n]
}
当然,如果您喜欢单衬里,您可以使用:

awk 'BEGIN{j=1}++i>3{i=1;++j}{a[j,i]=$0}END{for(m=j;m>0;--m)for(n=1;n<=3;++n)print a[m,n]}' file.txt
awk中的另一种方式

awk '{a[i]=a[i+=(NR%3==1)]?a[i]"\n"$0:$0}END{for(i=NR/3;i>0;i--)print a[i]}' file
输入 输出
这是一场纯粹的狂欢≥4对于不太大的文件,这种可能性应该可以。 我们还假设文件中的行数是3的倍数

mapfile -t ary < /path/to/file
for((i=3*(${#ary[@]}/3-1);i>=0;i-=3)); do
    printf '%s\n' "${ary[@]:i:3}"
done
awk '{a[i]=a[i+=(NR%3==1)]?a[i]"\n"$0:$0}END{for(i=NR/3;i>0;i--)print a[i]}' file
a1
a2
a3
x1
x2
x3
b1
b2
b3
b1
b2
b3
x1
x2
x3
a1
a2
a3
mapfile -t ary < /path/to/file
for((i=3*(${#ary[@]}/3-1);i>=0;i-=3)); do
    printf '%s\n' "${ary[@]:i:3}"
done