sed: corte a linha X e anexe ao topo do arquivo

3

Eu gostaria de poder cortar a linha X e inserir a linha X na posição y (superior). Isso me ajudaria a reorganizar alguns arquivos de configuração.

Text example line number 1 <--- Append line 10 above line 1
Text example line number 2
Text example line number 3
Text example line number 4
Text example line number 5
Text example line number 6
Text example line number 7
Text example line number 8
Text example line number 9
Text example line number 10 <--- Cut or hold in buffer
Text example line number 11
Text example line number 12
Text example line number 13

até agora, a única coisa que encontrei é:

# Cuts line 10 and adds it to the end of file    
sed -n -e '10h;10!p;${g;p;}' file-01.txt

Mas não sei como colocar o conteúdo suspenso em outra linha que não a última.

Infelizmente, não estou tão familiarizado com sed. Há perguntas semelhantes no stackoverflow e aqui, mas não consegui modificá-las para atender às minhas necessidades.

Eu preferiria uma solução com sed mas, se ela puder ser alcançada mais facilmente com outras ferramentas como o awk, essas soluções também serão bem-vindas.

    
por caracal 22.11.2015 / 19:46

1 resposta

2

Usando sed

Vamos criar um arquivo de teste:

$ seq 10 >file

Para mover, digamos, a linha 5 para o topo de um arquivo:

$ sed '1,4{H;1h;d}; 5{p;x}' file
5
1
2
3
4
6
7
8
9
10

Como funciona

  • 1,4{H;1h;d}

    Isso salva as linhas de 1 a 4 no espaço de espera.

    Mais detalhadamente, H anexa a linha atual ao espaço de espera depois de anexar uma nova linha ao espaço de armazenamento. Para a linha 1, não queremos essa nova linha, então emitimos o comando 1h que envia a linha 1 para o espaço de espera sem nenhuma nova linha. O comando d exclui a linha atual do espaço de padrões para que ela não seja impressa ainda.

  • 5{p;x}

    Isto imprime a linha 5 e depois imprime o espaço de espera. p informa ao sed para imprimir o espaço do padrão (que contém a linha 5). x diz ao sed para colocar para trocar o padrão e manter espaço para que o que estava no espaço de retenção seja agora impresso.

Linhas após a linha 5 são transmitidas inalteradas.

Usando o awk

$ awk 'NR<5{s=s ORS $0;next} NR==5{print $0 s;next} 1' file
5
1
2
3
4
6
7
8
9
10

A lógica aqui é bem parecida com a do sed. Nós salvamos todas as linhas antes da linha 5 na variável s . Quando chegamos na linha 5, imprimimos seguidos por s. As linhas restantes são passadas inalteradas.

    
por 22.11.2015 / 20:18

Tags