Uma maneira muito simples e clara em TXR :
@(repeat)
@x0
@x1
@x2
@y0
@y1
@y2
@z0
@z1
@z2
@ (output)
@x0 @y0 @z0
@x1 @y1 @z1
@x2 @y2 @z2
@ (end)
@(end)
Executar:
$ txr reshape.txr data
a1 aa aaa
b1 bb bbb
c1 cc ccc
d1 dd ddd
e1 ee eee
f1 ff fff
g1 gg ggg
h1 hh hhh
i1 ii iii
Existem maneiras de condensar isso, mas você precisa trabalhar um pouco mais para compreendê-las, como:
@(repeat)
@ (collect :times 9)
@line
@ (end)
@ (bind (x y z) @(tuples 3 line))
@ (output)
@ (repeat)
@x @y @z
@ (end)
@ (end)
@(end)
Além disso, como alguém que sabe o que está fazendo no Awk pode implementar:
{ a[(NR-1)%9] = $0 }
!(NR%9) { print a[0], a[3], a[6]
print a[1], a[4], a[7]
print a[2], a[5], a[8] }
Saída:
$ awk -f reshape.awk data
a1 aa aaa
[ ... ]
i1 ii iii
E se esse codificador encontrar repetidos padrões print
repugnant:
{ a[(NR-1)%9] = $0 }
!(NR%9) { for (i = 0; i < 3; i++)
print a[i], a[i+3], a[i+6] }
Solução TXR Lisp:
[(opip (tuples 3) (tuples 3) (mappend transpose)
(mapcar (aret '@1 @2 @3')) tprint)
(get-lines)]
Executar:
$ txr reshape.tl < data
Na linha de comando: use -t
, elimine o tprint
:
$ txr -t '[(opip (tuples 3) (tuples 3) (mappend transpose)
(mapcar (aret '@1 @2 @3')))
(get-lines)]' < data
Isso funciona colocando a entrada em um pipeline que a transporta para
trigêmeos, em seguida, trigêmeos desses trios (basicamente matrizes 3x3 feitas de listas aninhadas). Essas matrizes são transpostas individualmente e suas linhas são então anexadas para formar uma lista gigante de trigêmeos. Esses trios são transformados em strings com o operador de aplicativo aret
partial como uma interpolação de strings e a saída com tprint
, que trata listas de strings como linhas para saída. A sintaxe
(aret '@1 @2 @3')
expande-se para algo parecido com
(lambda (. args)
(apply (lambda (arg1 arg2 arg3)
'@arg1 @arg2 @arg3')
args))
Basicamente, ele cria implicitamente uma função anônima de um argumento que trata seu argumento como uma lista de argumentos para aplicar a uma função anônima de 3 argumentos em que @1
, @2
e @3
denotam os argumentos. O corpo da função é derivado da expressão quasi-string original, substituindo esses parâmetros numéricos especiais por nomes de argumentos gerados por máquina.