espacio de patrón sed y espacio de retención

espacio de patrón sed y espacio de retención

Estaba pasando por esto y no podía entenderlo.

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

donde el archivo cat es:

 foo
 foo
 bar

por qué lo hay 1!Hporque para mí 1hsobrescribe el espacio del patrón y 1!Hno sirve de nada

Pero el sed one liner parece funcionar bien.

Respuesta1

VerLa respuesta de @manatworkpor el motivo real 1h;1!H, pero quería agregar una nota de portabilidad.

La sintaxis estándar y portátil debería ser:

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

De lo contrario, no funcionará en la mayoría de sedlas implementaciones, por ejemplo las tradicionales de Unix.

Esto \nse entiende en el lado izquierdo del scomando, pero debe usar una barra invertida seguida de un carácter de nueva línea real en el lado derecho. También necesita el espacio ;entre el scomando y }y ningún espacio antes del p.

También puede almacenar el contenido del archivo en el espacio del patrón en lugar del espacio de retención:

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

Pero tanto con el patrón como con el espacio de retención, la mayoría de sedlas implementaciones solo funcionarán con archivos pequeños, ya que la mayoría de las implementaciones que no son GNU tienen un tamaño limitado para ellos (y POSIX solo requiere que puedan contener 8 kiB de datos).

De forma portátil, sería mejor que usaras perl:

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

Sin embargo , debido a que el tamaño no está limitado en perlGNU, sedtenga en cuenta que puede tener una incidencia en el rendimiento del sistema, ya que puede terminar usando toda la memoria del sistema si no ha establecido límites administrativos en el uso de memoria por proceso.

Respuesta2

por qué hay 1!H porque para mí 1h sobrescribe el espacio del patrón y 1!H no sirve de nada

No se produce ninguna sobrescritura ya que no se ejecutan en la misma línea 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

Esto es necesario porque según 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.

Entonces, si usa solo Hpara agregar todas las líneas, habrá una nueva línea adicional antes de la primera línea:

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

información relacionada