Unix tem essas pequenas ferramentas maravilhosas chamadas cut
e paste
. A ferramenta cut
extrairá um conjunto de colunas de sua entrada, enquanto a ferramenta paste
insere colunas. Nós estaremos usando estes.
Eu não vou me importar muito com o seu pipeline (agora, mas veja o final desta resposta), estou apenas preocupado com o problema de trocar as colunas.
Digamos que eu tenha esses dados em um arquivo chamado cols.txt
:
$ cat cols.txt
1 a
2 b
3 c
$ paste -d ' ' cols.txt cols.txt
1 a 1 a
2 b 2 b
3 c 3 c
O utilitário paste
geralmente insere uma tabulação entre colunas, mas aqui nós dissemos para inserir um espaço ( -d ' '
).
Depois, é só extrair as segunda e terceira colunas da saída de paste
com cut
:
$ paste -d ' ' cols.txt cols.txt | cut -d ' ' -f 2,3
a 1
b 2
c 3
Dissemos a cut
que temos espaços como "separadores de campos" ( -d ' '
, caso contrário, os separadores) e que gostaríamos de ter os campos 2 e 3 ( -f 2,3
), por favor. (Infelizmente, apenas pedindo cut
para as colunas " 2,1
" na entrada original, não trocará as colunas.)
Então, no final, não há necessidade de mágica de expressões regulares confusas aqui.
Voltar para o seu pipeline. Vamos acabar com isso. Parece que você deseja inserir o número da linha em cada linha. Há outra ferramenta Unix para isso chamada nl
("number lines"):
$ nl abc.txt
1 a
2 b
3 c
Você tem números de linha para cada linha não vazia por padrão, precedidos por alguns espaços para preenchimento e delimitados da linha original por um caractere de tabulação. Você também quer numerar linhas vazias, use
$ nl -b a abc.txt
Até onde eu sei, você não pode obter nl
para colocar os números de linha à direita da linha, mas isso não é um problema porque temos uma solução que trocará duas colunas de entrada:
$ paste <(nl abc.txt) <(nl abc.txt) | cut -f 2,3
a 1
b 2
c 3
Acabamos de especificar os delimitadores aqui. nl
irá inserir espaços seguidos por um número de linha e uma tabulação no início de cada linha. paste
insere uma tabulação entre suas colunas e cut
corta as guias, então funciona.
Se você quiser um único espaço entre suas colunas (agora há uma guia e alguns espaços), adicione | tr -s '\t' ' '
ao comando. Isso irá mudar ("transliterar") todas as abas para espaços, e "espremer" ( -s
) os espaços consecutivos resultantes em um espaço.
Se você quiser uma vírgula e um espaço, use | tr '\t ' ', '
:
$ paste <(nl abc.txt) <(nl abc.txt) | cut -f 2,3 | tr -s '\t ' ', '
a, 1
b, 2
c, 3
Isso funciona em um arquivo com várias palavras em cada linha, mas falhará em arquivos que contenham caracteres de guias:
$ cat abc.txt # no tabs in this file though
a text there is a
b goes hole in my
c here pants
$ paste <(nl abc.txt) <(nl abc.txt) | cut -f 2,3
a text there is a 1
b goes hole in my 2
c here pants 3