Como o comando sed '1! G; h; $! d' inverte o conteúdo de um arquivo?

20

A minha pergunta está relacionada com a solução sed específica dada em esta resposta para esta questão de < href="https://unix.stackexchange.com/q/146100/28032"> inverter grepping . A solução sed / grep que não consigo decifrar é a seguinte:

sed '1!G;h;$!d' file

Alguém pode decifrar este comando?

Eu sei do VI (M) saber que G denota a última linha do arquivo e que em sed a bang (!) seguido por um endereço funciona um pouco como grep -v , ou seja, não corresponderá a esse linha. Mas como um todo, o script inline acima está além de mim.

    
por Geek 30.09.2015 / 16:04

1 resposta

35

Isso inverte o arquivo linha por linha.

sed '1!G;h;$!d' file

Primeiro, sed tem um espaço de espera e um espaço de padrão . Temos que distinguir entre eles antes de nos concentrarmos nesse comando específico.

Quando sed lê uma nova linha, ela é carregada no espaço de padrão. Portanto, esse espaço é sobrescrito toda vez que uma nova linha é processada. Por outro lado, o espaço de espera é consistente durante todo o processamento e os valores podem ser armazenados lá para uso posterior.

Para o comando:

Existem três comandos nesta declaração: 1!G , h e $!d

  • 1!G significa que o comando G é executado em todas as linhas, exceto na primeira (o ! nega o 1 ). G significa acrescentar o que está no espaço de armazenamento no espaço de padrões.

  • h aplica-se a todas as linhas. copia o espaço padrão para o espaço de armazenamento (e sobrescreve).

  • $!d aplica-se a todas as linhas, exceto a última ( $ representa a última linha, ! nega isso). d é o comando para excluir a linha (espaço de padrão).

  1. Agora, quando a primeira linha for lida, sed executará o comando h . A primeira linha é copiada para o espaço de espera. Em seguida, ele é excluído, pois corresponde à condição $! . sed continua com a segunda linha.
  2. A segunda linha corresponde à condição 1! (não é a primeira linha) e, portanto, o espaço de armazenamento (que possui a primeira linha) é anexado ao espaço de padrão (que possui a segunda linha). Depois disso, no espaço de padrão, existe agora a segunda linha seguida pela primeira linha, delimitada por uma nova linha. Agora, o comando h se aplica (como em todas as linhas); tudo o que está no espaço de padrão é copiado para o espaço de espera. A terceira declaração ( $!d ) se aplica: A linha é excluída do espaço de padrões.
  3. O passo 2 agora é feito com todas as linhas. Nós pulamos para a última linha.
  4. Na última linha ( $ ), quase toda a Etapa 2 está concluída, mas não a parte de exclusão ( d ). sed , quando invocado sem -n , imprime o espaço do padrão automaticamente no final do processamento para cada linha de entrada. Portanto, quando não excluído, o espaço do padrão é impresso. Ele contém agora todas as linhas em ordem inversa .
por 30.09.2015 / 16:15

Tags