Bem, isso não é particularmente elegante, mas fará o que você precisa. Pelo menos, no exemplo que você postou:
perl -ne 'while(s/(\[(\d),\s*\[.+?\]\])//){push @{$k{$2}},$1 . ",";}
END{ print "[@{$k{$_}}]\n" for keys(%k)}' file.txt |
sed 's/,\]$/\]/' | sort
A execução do comando acima em um arquivo chamado file.txt
que contém as linhas do seu exemplo fornece a seguinte saída:
[[0, [0, '1']], [0, [1, '5']], [0, [2, '9']]]
[[1, [0, '2']], [1, [1, '6']], [1, [2, '10']]]
[[2, [0, '3']], [2, [1, '7']], [2, [2, '11']]]
[[3, [0, '4']], [3, [1, '8']], [3, [2, '12']]]
Explicação
Eu não vou explicar em detalhes, já que este é realmente um pequeno programa e usa alguns recursos do Perl. A ideia básica do script Perl é encontrar todos os casos de [\d, [.+?]]
, em que \d
é qualquer número e .+?]]
é tudo para o primeiro ]]
. Isso basicamente irá coletar todos os diferentes sub-arrays ou tuplas, ou seja o que for, e salvá-los em um hash de arrays cuja chave é o primeiro dígito, aquele em que você deseja classificar. Uma vez que o arquivo inteiro tenha sido processado, ele imprimirá cada array do hash. Esta é a saída do script sozinho:
$ perl -ne 'while(s/(\[(\d),\s*\[.+?\]\])//){push @{$k{$2}},$1 . ",";}
END{ print "[@{$k{$_}}]\n" for keys(%k)}' file.txt
[[1, [0, '2']], [1, [1, '6']], [1, [2, '10']],]
[[3, [0, '4']], [3, [1, '8']], [3, [2, '12']],]
[[0, [0, '1']], [0, [1, '5']], [0, [2, '9']],]
[[2, [0, '3']], [2, [1, '7']], [2, [2, '11']],]
Eu estou separando cada sub-array com ,
, mas isso significa que eu recebo um extra no final, então eu uso sed
para remover isso.
$ perl -ne 'while(s/(\[(\d),\s*\[.+?\]\])//){push @{$k{$2}},$1 . ",";}
> END{ print "[@{$k{$_}}]\n" for keys(%k)}' file.txt |
> sed 's/,\]$/\]/'
[[1, [0, '2']], [1, [1, '6']], [1, [2, '10']]]
[[3, [0, '4']], [3, [1, '8']], [3, [2, '12']]]
[[0, [0, '1']], [0, [1, '5']], [0, [2, '9']]]
[[2, [0, '3']], [2, [1, '7']], [2, [2, '11']]]
Finalmente, você também queria isso classificado, mas como agora eles estão organizados pelo primeiro caractere, um sort
simples será o seguinte:
$ perl -ne 'while(s/(\[(\d),\s*\[.+?\]\])//){push @{$k{$2}},$1 . ",";}
END{ print "[@{$k{$_}}]\n" for keys(%k)}' file.txt |
sed 's/,\]$/\]/' | sort
[[0, [0, '1']], [0, [1, '5']], [0, [2, '9']]]
[[1, [0, '2']], [1, [1, '6']], [1, [2, '10']]]
[[2, [0, '3']], [2, [1, '7']], [2, [2, '11']]]
[[3, [0, '4']], [3, [1, '8']], [3, [2, '12']]]