2010-03-03 13 views
29

Sono curioso, perché sed ha bisogno di 3 \ solo per riconoscerne uno? Capisco che ne abbia bisogno 2, ma io no.Perché sed richiedono 3 barre inverse per un normale backslash?

EDIT: ecco un esempio sul mio computer Windows, utilizzando Cygwin:

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

Se non aggiungo 3 barre rovesciate, ho un

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

mostra quello che hai – ghostdog74

+0

Non lo fa. Mostraci perché pensi che sia così. –

+0

la shell sta consumando un ulteriore livello di backslashing? – p00ya

risposta

31

Sono stato in grado di riprodurre questo comportamento utilizzando Vista e Cygwin 1.7.0.

  • rovesciano due producono l'errore
  • sia tre o quattro barre rovesciate funzionano
  • Cinque dà lo stesso errore

rovesciare due diventano una singola barra rovesciata nel guscio che poi in sed sfugge alla barra in avanti che è il delimitatore centrale.

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

Tre di loro: I primi due diventano uno nel guscio che poi sfuggire il terzo in sed

\\\/ -> \\/ 

Four: Ogni coppia diventare quelli singoli nel guscio poi la prima risultante uno fughe il secondo in sed

\\\\/ -> \\/ 

Edit:

Oh, ho dimenticato di dire che sia le virgolette singole che le virgolette hanno funzionato allo stesso modo per me (cmd.exe non fa la distinzione che Bash, et al, fa).

+0

Ma 's/\\ [0-9] * //' sembra corretto se il carattere dopo il backslash non è tagliato – Timo

4

Si prega di mostrare un esempio di ciò che si avere in futuro. in sed, dire che si desidera sostituire un "\" con pipe (|), per esempio

$ cat file 
asklfja \ asf 

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

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

basta per sfuggire una volta.

Modifica: per l'esempio di @OP, poiché si utilizza cmd.exe e non bash/ksh, cmd.exe non ama le virgolette singole. Non riesco a produrre il tuo scenario. Questo funziona per il mio GNU sed su Windows utilizzando 2 barre

esempio

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

@ ghostdog74, ho pubblicato un esempio. – Geo

+0

@geo, vedere la mia modifica. – ghostdog74

+0

Non sto utilizzando bash, ghostdog74 e con le virgolette singole, ottengo lo stesso errore. – Geo

0

Credo che, supponendo \\\n o \\\t a tre barre inverse lì, ma in realtà, i suoi 2 backslash e un altro pattern

backslash   \\ 
    newline   \n 
    tab    \t 

anche, / potrebbe essere necessario eseguire l'escape perché in s/.../, / viene utilizzato per le parti aperte e chiuse.

così /\\\/\// sarebbe \\ + \/ + \/ secondo il tuo esempio aggiornato

+0

Mi piace il tuo metodo di spiegazione, potresti dare un'occhiata a questo e provare a rispondere? https://superuser.com/questio ns/1249497/sed-needs-n-to-append-new-line? noredirect = 1 # comment1834908_1249497 –

8

La shell (probabilmente bash) sta facendo la sua fuga, e che si sta confondendo. È possibile utilizzare un comando echo per vedere ciò che viene passato, o è facile scrivere un programma personalizzato (comunemente denominato "ShowArgs" o simili):

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

È anche possibile utilizzare le virgolette singole, che sono trattati in modo diverso in bash.

+0

Sto usando 'cmd.exe' di Windows, non bash. – Geo

+0

@Geo: ho indovinato bash perché hai citato cygwin, ma anche altre shell fanno fuggire. –

1

Nella mia versione di CYGWIN, funziona come dice il poster originale, ma funziona in modo diverso (normalmente) se uso virgolette singole.

 
$ 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

Sostituzione di una barra rovesciata con due sulla mia Cygwin richiede questa espressione:

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

5

Ciò è dovuto alla regola di analisi delle stringhe con virgolette sh.

Posix specifica come sh analizza le stringhe con doppie virgolette.

Il backslash conserva il suo significato speciale come carattere di escape (vedi fuga Character (Backslash)) solo quando seguito da uno dei seguenti caratteri quando considerato speciale: $ `" \

In altre parole, sh sinistre, il backslash seguito da caratteri diversi da $ '".

Quindi, se sh incontra la stringa con doppia citazione sed "s/\\\/\//", sh la analizza come segue.

  1. I primi due \\ è cambiato in \. Perché il primo \ è seguito dal secondo \.
  2. Il terzo e il quarto \ sono ancora lasciati nella stringa. Perché entrambi sono seguiti da /, che non è speciale nella stringa doppia citazione.

Dopo pasring, sh passa la stringa s/\\/\// a sed, che sostituisce la prima occorrenza di \ in /.

Con lo stesso ragionamento, quando sh incontra la stringa, "sed s/\\\\/\//", sh passa /\\/\// a sed, che sostituisce anche la prima occorrenza di \ in /.

Problemi correlati