sed espaço padrão e espaço de espera

sed espaço padrão e espaço de espera

eu estava passando por isso e não consegui entender.

sed -n '1h; 1!H; ${ g; s/foo\nbar/bla\nblub/ p }' file.

onde o arquivo cat está:

 foo
 foo
 bar

porque existe 1!Hporque para mim 1hsobrescreve o espaço do padrão e 1!Hnão adianta

Mas o sed one liner parece funcionar bem.

Responder1

VerResposta de @manatworkpelo motivo real 1h;1!H, mas gostaria de adicionar uma nota de portabilidade.

A sintaxe padrão e portátil deve ser:

sed -n '1h; 1!H; ${ g; s/foo\nbar/bla\
blub/p;}'

Caso contrário, não funcionará na maioria das sedimplementações, por exemplo nas tradicionais do Unix.

Isso é \nentendido no lado esquerdo do scomando, mas você deve usar um caractere de barra invertida seguido por um caractere de nova linha real no lado direito. Você também precisa de espaço ;entre o scomando e }e nenhum espaço antes de p.

Você também pode armazenar o conteúdo do arquivo no espaço padrão em vez do espaço de espera:

sed -n '
  :1
  $!{
   N;b1
  }
  s/foo\nbar/blah\
blup/p'

Mas tanto com padrão quanto com espaço de retenção, com a maioria seddas implementações que funcionarão apenas com arquivos pequenos, já que a maioria das implementações não-GNU tem um tamanho limitado para eles (e o POSIX exige apenas que eles sejam capazes de armazenar 8kiB de dados).

Portavelmente, seria melhor usar perl:

perl -0777 -ne 'print if s/foo\nbar/blah\nblup/'

Como o tamanho não é limitado no perlGNU, sedno entanto, tome cuidado, pois isso pode afetar o desempenho do sistema, pois pode acabar usando toda a memória do sistema se você não tiver limites definidos administrativamente para o uso de memória por processo.

Responder2

por que existe 1!H porque para mim 1h substitui o espaço do padrão e 1!H é inútil

Nenhuma substituição ocorre porque eles não são executados na mesma linha de entrada:

1h   # when input line number is 1, copy pattern space to hold space
1!H  # when input line number is not 1, append pattern space to hold space

Isso é necessário porque de acordo com info sed:

`H'
     Append a newline to the contents of the hold space, and then
     append the contents of the pattern space to that of the hold space.

Portanto, se você usar apenas Hpara anexar todas as linhas, haverá uma nova linha extra antes da primeira linha:

bash-4.2$ seq 3 | sed -n 'H; ${g; p;}'

1
2
3
bash-4.2$ seq 3 | sed -n '1h; 1!H; ${g; p;}'
1
2
3

informação relacionada