Você pode usar o awk para essa finalidade
awk '{ for(i = 2; i <= NF; i++) { print $i,$1; } }' file
O loop for vai do segundo campo até o último e cada campo é impresso com o primeiro campo anexado
No shell osx, dado um fluxo com essas linhas, onde o primeiro token é uma chave, o primeiro caractere na linha sempre corresponderá a [a-z]
, os tokens restantes serão sempre apenas numéricos, haverá um número variável de eles e apenas espaços únicos separam os tokens:
key [1] [...] [n]
---- --------------------
key1 17 89 52
key2 5 189 6 3 5 21
Como posso emitir a seguinte saída (independente do número de tokens em cada linha) sem fazer apenas substituições repetidas vezes?
17 key1
89 key1
52 key1
5 key2
189 key2
6 key2
3 key2
5 key2
21 key2
(Também é perfeitamente correto trocar chaves ou números, ou cada linha permanecer uma linha separada por espaços ao invés de novas linhas como key1 17 key1 89 key1 52
, pois eu posso trocar tokens ou dividi-los em múltiplas linhas facilmente). / p>
Atualmente, estou usando sed
para substituir sucessivamente cada próximo número sem chave, mas isso parece ineficiente, e tenho de garantir que canalize para sed
mais vezes do que o número máximo de tokens, o que poderia aumentar (e por que mais você acha que eu estou aqui?):
sed -E 's/^([a-z][^ ]*) ([0-9]+) / \n /g' filename.txt | sed ... | sed ...
Se eu pudesse me dar ao luxo de investigar awk
, tenho certeza de que isso funcionaria. Talvez cut
possa fazer o trabalho ou uma das outras ferramentas que podem trabalhar efetivamente com tokens.
Como você faria isso de maneira eficiente tanto no código quanto no tempo de processamento?
sed
é adequado para essa tarefa. Apenas aprimorando seu código sed, temos:
sed -E '
s/^([a-z][^ ]*) ([0-9]+)/ \n/
/\n/P;D
' filename.txt
Saída:
17 key1
89 key1
52 key1
5 key2
189 key2
6 key2
3 key2
5 key2
21 key2
Explicação:
global /g flag
. \n
após a operação de inversão, para que possamos ser capazes de use o comando P
, que imprime apenas até a primeira nova linha no espaço padrão. P
com /\n/
para evitar um loop infinito. D
é excluído da primeira nova linha no espaço de padrão e, com o que resta do espaço de padrão, leva o controle de volta à parte superior do script. IOW, o que você fez é, fornecido por um mecanismo de looping implícito. s/// --- P --- D --- s/// --- P --- D ...........
. sed
inicia um novo ciclo de leitura e você já sabe o que acontece .... HTH. Tags text-processing osx