¿Por qué sed requiere 3 barras diagonales inversas para una barra diagonal inversa regular?

Tengo curiosidad, ¿por qué sed necesita 3 \ solo para reconocer uno? Entendí que necesitaba 2, pero 3 no.

EDITAR: aquí hay un ejemplo en mi computadora con Windows, usando Cygwin:

 echo "sample_input\whatever" | sed "s/\\\/\//" 

Si no agrego 3 barras invertidas, obtengo una

 sed: -e expression #1, char 7: unterminated s' command 

Pude reproducir este comportamiento usando Vista y Cygwin 1.7.0.

  • Dos barras invertidas producen el error
  • tres o cuatro barras invertidas funcionan
  • Cinco da el mismo error

Dos barras diagonales inversas se convierten en una sola barra invertida en el caparazón, que a su vez se escapa de la barra inclinada que es el delimitador central.

 \\/ -> \/ (which makes the forward slash a regular character instead of a delimiter) 

Tres de ellos: los dos primeros se convierten en uno en el caparazón y luego escapan del tercero en sed

 \\\/ -> \\/ 

Cuatro: cada par se convierte en uno solo en el caparazón y luego el primero resultante escapa el segundo en sed

 \\\\/ -> \\/ 

Editar:

Ah, se me olvidó decir que tanto las comillas simples como las comillas dobles funcionaban igual para mí ( cmd.exe no hace la distinción que Bash, et al, hace).

Tu caparazón (probablemente bash) está escapando, y eso te confunde. Puede usar un comando echo para ver lo que se está pasando, o es fácil escribir un progtwig personalizado (comúnmente llamado “showargs” o similar):

 $ echo "s / \\\ / \ //"
 s / \\ / \ //
 $ echo "s / \\ / \ //"
 s / \ / \ //

También puede usar comillas simples, que se tratan de manera diferente en bash.

Eso se debe a la regla de análisis de cadenas de doble cita de sh .

Posix especifica cómo sh analiza cadenas entre comillas dobles.

La barra diagonal inversa conservará su significado especial como carácter de escape (ver Carácter de escape (barra invertida)) solo cuando sea seguido por uno de los siguientes caracteres cuando se considere especial: $ `” \

En otras palabras, deja la barra invertida seguida de caracteres que no son $ ‘”.

Por lo tanto, si sh encuentra con la cadena de caracteres citada sed "s/\\\/\//" , sh analiza de la siguiente manera.

  1. Los primeros dos \\ se cambian a \ . Porque el primero \ es seguido por el segundo \ .
  2. El tercero y el cuarto \ quedan en la cadena. Debido a que ambos son seguidos por / , que no es especial en la cadena de comillas dobles.

Después de pasar, sh pasa la cadena s/\\/\// a sed , que sustituye la primera aparición de \ en / .

Con el mismo razonamiento, cuando sh encuentra con la cadena, "sed s/\\\\/\//" , sh pasa /\\/\// a sed , que también sustituye a la primera aparición de \ en / .

Por favor, muestre un ejemplo de lo que tiene en el futuro. en sed, digamos que quieres reemplazar una ” \ ” por tubería (|), por ejemplo

 $ cat file asklfja \ asf $ sed 's/\\/|/g' file asklfja | asf $ sed 's%\\%|%g' file #using different delimiter asklfja | asf 

solo necesitas escapar de ella una vez.

Editar: al ejemplo de @ OP, ya que está usando cmd.exe y no bash / ksh, a cmd.exe no le gustan las comillas simples. No puedo producir tu escenario. Esto funciona para mi GNU sed en windows usando 2 barras inclinadas

p.ej

 C:\test>echo "sample_input\whatever" | sed "s/\\/\//" "sample_input/whatever" 

En mi versión de CYGWIN, funciona como dice el cartel original, pero funciona de manera diferente (normalmente) si utilizo comillas simples.

 $ echo "sample_input \ whatever" |  sed 's / \\ / \ //'
 sample_input / whatever
 $ echo "sample_input \ whatever" |  sed "s / \\ / \ //"
 sed: -e expresión # 1, char 7: comando `s 'no terminado

Hmmm …

Supongo que supones que \\\n o \\\t son tres barras diagonales inversas, pero en realidad son 2 barras diagonales inversas y otros patrones

  backslash \\ newline \n tab \t 

también, / podría tener que escapar porque en s/.../ , / está usando para abrir y cerrar partes.

so /\\\/\// sería \\ + \/ + \/ acuerdo con su ejemplo actualizado

Reemplazar una barra invertida con dos en mi Cygwin requiere esta expresión:

sed -e “s | \\ | \\\\ | g”