¿Alguien puede explicar cómo funciona este sed
comando?
sed 's@+@ @g;s@%@\\x@g' | xargs -0 printf "%b"
sed
esta manera! :)
¿Alguien puede explicar cómo funciona este sed
comando?
sed 's@+@ @g;s@%@\\x@g' | xargs -0 printf "%b"
sed
esta manera! :)
Respuestas:
En sed, los comandos sustitutos generalmente se escriben como s/pattern/replacement/options
. Sin embargo, no es necesario usarlo /
; puede usar otros caracteres si es conveniente, por lo que podría ser s@pattern@replacement@options
o s:foo:bar:g
. s@+@ @g
es como s/+/ /g
: reemplazar todo +
con espacios. De manera similar, s@%@\\x@g
reemplaza todo %
con \x
(una barra invertida simple es un carácter de escape en sed, por lo que necesita dos para obtener una barra invertida real).
Una cadena como foo+%2Fbar
se convertirá entonces foo \x2Fbar
. printf "%b"
expandirá las secuencias con barra invertida como \x2F
(el carácter ASCII cuyo valor hexadecimal es 2F, que es /
) para finalmente darte foo /bar
.
El comando sobre el que está preguntando para decodificar +
es y %
secuencias de URL no es solo un sed
comando, es una tubería que procesa la entrada sed
y luego la canaliza xargs
para su posterior procesamiento. Primero veamos el sed
comando:
sed 's@+@ @g;s@%@\\x@g'
Es posible que esté más acostumbrado a verlo en /
lugar de @
como el separador, lo que fácilmente podría haberse hecho aquí sin complicaciones, ya que no /
aparece en ninguno de los patrones de búsqueda ni en ninguno de los textos de reemplazo. Este comando es equivalente:
sed 's/+/ /g;s/%/\\x/g'
Como /
, @
es un personaje de puntuación perfectamente bueno para sed
.
En cada línea de entrada:
s@+@ @g
( s/+/ /g
) sustituye ( s
) ocurrencias de +
con un espacio. Esto afecta a todos los +
es en una línea ( g
), no solo a la primera.
;
finaliza la acción ("comando") y le permite especificar otro en el mismo "script".
s@%@\\x@g
( s/%/\\x/g
) sustituye ( s
) ocurrencias de %
con \x
. Como antes, actúa sobre todos en lugar de solo el primero de cada línea ( g
).
En \\x
el \\
representa solo uno \
porque \
tiene un significado especial para sed
. Su significado especial es en realidad como el personaje que usas para quitar el significado especial de otro personaje que viene después que de otro modo tendría un significado especial. Por lo tanto, se debe escapar como \\
.
Ahora veamos un xargs
comando cuyo propósito es ejecutar printf
.
xargs
construye líneas de comando. Si ejecuta , donde es una o más palabras, se ejecuta con argumentos de línea de comandos adicionales leídos desde su entrada. En este caso, la entrada a es la salida de , debido a la tubería ( ). Normalmente interpreta cualquier espacio en blanco en su entrada para significar que el texto anterior y posterior constituye argumentos separados, pero la opción hace que se dividan los argumentos en las apariciones del carácter nulo .xargs command...
command...
xargs
command...
xargs
sed
|
xargs
-0
En el uso previsto de su comando, no aparecerá un carácter nulo y xargs
se ejecutará printf %b
con solo un argumento adicional en la línea de comandos, el resultado del sed
comando. Por lo tanto, aunque no es equivalente en general, en este caso, toda la tubería podría haberse escrito así usando la sustitución de comandos en lugar de xargs
:
printf '%b\n' "$(sed 's/+/ /g;s/%/\\x/g')"
En cuanto a lo que printf
se pretende hacer aquí, como muru dice que el %b
especificador de formato consume e imprime un argumento (como %s
) pero provoca escapes de barra invertida, del tipo que sed
se escribió para generar el comando en el lado izquierdo de la tubería, para traducir en los personajes que representan .
Supongamos que ejecuto ese comando y paso http://foldoc.org/debugging%20by%20printf
como entrada. Obtengo http://foldoc.org/debugging by printf
como salida, porque las %20
secuencias se traducen en espacios.
Esa es la belleza de sed
, aplica sus paradigmas a sí mismo ... Después de la orden (por ejemplo, s
o tr
o nada), el siguiente carácter es considerado el separador.
Debe elegir sabiamente para evitar interferencias con el shell y el comando en sí mismo, y mantener la cosa legible, pero es perfectamente válido escribir algo tan horrible como:
echo 'arrival' | sed srarbrg
... y brrivbl
como resultado, que es lo que esperas. Puede divertirse haciéndolo realmente críptico, como en:
echo 'arrival' | sed s\fa\fb\fg # \f is form feed, chr(12)
El uso común es usar la barra como delimitador, pero cuando su expresión contiene el delimitador, hace que sea más fácil agarrar cuál es la intención. Su delimitador puede ser cualquier cosa en el rango ASCII8 (delimitadores multibyte como £
provocar un error).
Solo recuerda que el objetivo es hacer las cosas más fáciles, no más crípticas.
sed "snack is an apple or something" <<< "I sed your snack is an apple or something"
sed
comandos como acertijos, ¿qué tan geek es eso?