2010-03-03 16 views
29

Tengo curiosidad, ¿por qué sed necesita 3 \ solo para reconocer uno? Entendí que necesitaba 2, pero 3 no.¿Por qué sed requiere 3 barras diagonales inversas para una barra diagonal inversa regular?

EDIT: he aquí un ejemplo en mi equipo Windows, utilizando Cygwin:

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

Si no añado 3 barras invertidas, consigo un

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

muestra lo que tienes – ghostdog74

+0

No es así. Muéstranos por qué crees que lo hace. –

+0

¿Su caparazón consume un nivel extra de backslashing? – p00ya

Respuesta

31

Pude reproducir este comportamiento utilizando Vista y Cygwin 1.7.0.

  • dos barras invertidas producen el error
  • ya sea tres o cuatro barras invertidas trabajan
  • Cinco da el mismo error

dos barras invertidas se convierten en una sola barra invertida en la cáscara que luego en sed escapa de la barra diagonal 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 la cáscara que luego escapar de la tercera en sed

\\\/ -> \\/ 

Cuatro: Cada par convertirse en los individuales en la carcasa, entonces el primero resultante se escapa la segunda en SED

\\\\/ -> \\/ 

Editar:

Oh, 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).

+0

Pero 's/\\ [0-9] * //' parece correcto si el carácter después de la barra invertida no es barra inclinada – Timo

4

Por favor, muestran un ejemplo de lo que tener en el futuro. en la sed, digamos que desea reemplazar un "\" con la barra vertical (|), por ejemplo

$ cat file 
asklfja \ asf 

$ sed 's/\\/|/g' file 
asklfja | asf 

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

sólo tiene que escapar de una vez.

Editar: Para el 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 sed de GNU para Windows utilizando 2 barras inclinadas

por ejemplo

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

@ ghostdog74, publiqué un ejemplo. – Geo

+0

@geo, mira mi edición. – ghostdog74

+0

No estoy usando bash, ghostdog74, y con comillas simples, obtengo el mismo error. – Geo

0

supongo, que asumiendo \\\n o \\\t como tres barras invertidas allí, pero en realidad, sus 2 barras invertidas y otros patrones

backslash   \\ 
    newline   \n 
    tab    \t 

también, / podría necesitar escapar porque en s/.../, / se está utilizando para abrir y cerrar piezas.

por lo /\\\/\// habría \\ + \/ + \/ de acuerdo a su ejemplo actualizado

+0

Me gusta tu método para explicar, ¿podrías echarle un vistazo e intentar responderlo? https://superuser.com/questio ns/1249497/sed-needs-n-to-append-new-line? noredirect = 1 # comment1834908_1249497 –

8

Su cáscara (probablemente bash) está haciendo su propio escape, y que es confuso. Se puede utilizar un comando echo para ver lo que se está pasando, o que es fácil escribir un programa personalizado (comúnmente llamado "ShowArgs" o similar):

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

También puede utilizar comillas simples, que son tratadas de manera diferente en intento.

+0

Estoy usando 'cmd.exe' de Windows, no bash. – Geo

+0

@Geo: Adiviné bash porque mencionaste a cygwin, pero otras conchas también escapan. –

1

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

 
$ echo "sample_input\whatever" | sed 's/\\/\//' 
sample_input/whatever 
 
$ echo "sample_input\whatever" | sed "s/\\/\//" 
sed: -e expression #1, char 7: unterminated `s' command 

Hmmm ..

0

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

sed -e "s | \\ | \\\\ | g"

5

Esto se debe a la regla de análisis de cadenas de comillas dobles de sh.

Posix especifica cómo sh analiza las comillas dobles.

La barra invertida conservará su significado especial como un carácter de escape (véase el carácter de escape (barra invertida)) sólo cuando seguido por uno de los siguientes caracteres cuando se considera especial: $ `" \

En es decir, sh deja la barra invertida seguida de caracteres que no sean $ '".

Por lo tanto, si sh cumple la cadena de comillas dobles sed "s/\\\/\//", sh lo analiza de la siguiente manera.

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

Después pasring, sh pasa la cadena s/\\/\//-sed, que sustituye la primera ocurrencia de \ en /.

Con mismo razonamiento, cuando sh cumple con la cadena, "sed s/\\\\/\//", sh pasa /\\/\//-sed, que también sustituye la primera ocurrencia de \ en /.

Cuestiones relacionadas