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