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!H
porque para mim 1h
sobrescreve o espaço do padrão e 1!H
nã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 sed
implementações, por exemplo nas tradicionais do Unix.
Isso é \n
entendido no lado esquerdo do s
comando, 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 s
comando 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 sed
das 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 perl
GNU, sed
no 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 H
para 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