La forma normal de hacer esto es usar barras, pero eso puede volverse engorroso si busca y reemplaza algo con barras. Ese no es el caso aquí, por lo que, aunque está perfectamente bien, confunde a los futuros mantenedores como usted.
Thorbjørn Ravn Andersen
2
... y los lleva a aprender algo nuevo sobre sedesta manera! :)
postre
Respuestas:
15
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@optionso s:foo:bar:g. s@+@ @ges como s/+/ /g: reemplazar todo +con espacios. De manera similar, s@%@\\x@greemplaza 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+%2Fbarse 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.
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 \\xel \\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 xargscomando cuyo propósito es ejecutar printf.
xargsconstruye 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...xargscommand...xargssed|xargs-0
En el uso previsto de su comando, no aparecerá un carácter nulo y xargsse ejecutará printf %bcon solo un argumento adicional en la línea de comandos, el resultado del sedcomando. 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 printfse pretende hacer aquí, como muru dice que el %bespecificador de formato consume e imprime un argumento (como %s) pero provoca escapes de barra invertida, del tipo que sedse 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%20printfcomo entrada. Obtengo http://foldoc.org/debugging by printfcomo salida, porque las %20secuencias se traducen en espacios.
Esa es la belleza de sed, aplica sus paradigmas a sí mismo ... Después de la orden (por ejemplo, so tro 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 brrivblcomo 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.
Funcionando con la idea críptica, este es un comando sed válido, aunque no hace nada útil:sed "snack is an apple or something" <<< "I sed your snack is an apple or something"
wjandrea
¡Agradable! Sí, también puedes usar sedcomandos como acertijos, ¿qué tan geek es eso?
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 sers@pattern@replacement@options
os:foo:bar:g
.s@+@ @g
es comos/+/ /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á entoncesfoo \x2Fbar
.printf "%b"
expandirá las secuencias con barra invertida como\x2F
(el carácter ASCII cuyo valor hexadecimal es 2F, que es/
) para finalmente dartefoo /bar
.fuente
El comando sobre el que está preguntando para decodificar
+
es y%
secuencias de URL no es solo unsed
comando, es una tubería que procesa la entradased
y luego la canalizaxargs
para su posterior procesamiento. Primero veamos elsed
comando: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:Como
/
,@
es un personaje de puntuación perfectamente bueno parased
.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 parased
. 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 ejecutarprintf
.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 delsed
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 dexargs
: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 quesed
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. Obtengohttp://foldoc.org/debugging by printf
como salida, porque las%20
secuencias se traducen en espacios.fuente
Esa es la belleza de
sed
, aplica sus paradigmas a sí mismo ... Después de la orden (por ejemplo,s
otr
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:
... y
brrivbl
como resultado, que es lo que esperas. Puede divertirse haciéndolo realmente críptico, como en: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.
fuente
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?