2012-01-21 21 views
12

Ho un documento di testo semplice, che voglio compilare all'interno di LaTeX. Tuttavia, a volte ha i caratteri "#", "$", "%", "&" e "_". Per compilare correttamente in LaTeX, devo prima sostituire questi caratteri con "#", "\ $", "\%", "\ &" e "_". Ho usato questa linea in sed:

sed -i 's/\#/\\\#/g' ./file.txt 
sed -i 's/\$/\\\$/g' ./file.txt 
sed -i 's/\%/\\\%/g' ./file.txt 
sed -i 's/\&/\\\&/g' ./file.txt 
sed -i 's/\_/\\\_/g' ./file.txt 

È corretto?

Sfortunatamente, il file è troppo grande per essere aperto in qualsiasi software della GUI, quindi controllare se la mia riga sed è corretta con un editor di testo è difficile. Ho provato a cercare con grep, ma la ricerca non funziona come previsto (ad esempio qui sotto, ho cercato per tutte le righe che contengono "$"):

grep "\$" file.txt 
  • Qual è il modo migliore per mettere "\" davanti di questi personaggi?
  • Come è possibile utilizzare grep per verificare correttamente le linee con le sostituzioni?
+1

Potete garantire che non ci sono caratteri speciali che sono GIÀ sfuggiti? – wim

+1

Come funziona il grep, se non come previsto? – chepner

+0

Quando eseguo 'grep" \ $ "file.txt' sembra che stampi tutto o quasi tutto. Non so perché stia stampando così tanto testo, dato che "$" è piuttosto raro. – Village

risposta

21

È possibile. fare la sostituzione con una singola chiamata a sed:.

sed -i -E 's/([#$%&_\])/\\&/g' file.txt 

il & nel testo di sostituzione riempie per qualsiasi singolo carattere è racchiuso tra parentesi noti che, poiché \ è il carattere LaTeX fuga, si dovrà fuggire anche nel file originale.

+1

Ben fatto! +1 –

+3

Le parentesi non sono necessarie. Alcune versioni di 'sed' non supportano' -E', ma usano '-r'. Alcune versioni di 'sed' richiedono un'estensione dopo' -i', ma dal momento che l'OP non ne ha fornito uno nella domanda è sicuro assumere che non è necessario. –

+2

Buoni punti, tutto. Stavo per dire che -E dipenderebbe dal fatto che la versione sia in uso, ma deve averlo eliminato dalla versione finale. – chepner

2

Penso che il tuo problema sia che bash stesso sta gestendo queste fughe.

  1. Quello che mi sembra giusto. Ma attenzione: sarà anche doppiamente sfuggire, ad es. a \# già sfuggito. Se questo non è ciò che vuoi, potresti voler modificare i tuoi pattern per verificare che non ci sia un \ già precedente.
  2. $ viene utilizzato per la sintassi di sostituzione del comando bash. Immagino che lo grep "\\$" file.txt dovrebbe fare quello che ti aspetti.
4
sed -i 's/\#/\\\#/g' ./file.txt 
sed -i 's/\$/\\\$/g' ./file.txt 
sed -i 's/\%/\\\%/g' ./file.txt 
sed -i 's/\&/\\\&/g' ./file.txt 
sed -i 's/\_/\\\_/g' ./file.txt 

Non è necessario il \ sulla prima (ricerca) stringa sulla maggior parte di loro, proprio $ (è un carattere speciale, che significa la fine di una riga, il resto non sono speciali) . E nella sostituzione, hai solo bisogno di due \\, non di tre. Inoltre, si potrebbe fare tutto in uno con diverse -e dichiarazioni:

sed -i.bak -e 's/#/\\#/g' \ 
      -e 's/\$/\\$/g' \ 
      -e 's/%/\\%/g' \ 
      -e 's/&/\\&/g' \ 
      -e 's/_/\\_/g' file.txt 

Non è necessario fare doppio sfuggire nulla (tranne il \\) perché questi sono single-citato. Nel tuo grep, $ sta interpretando l'escape perché è un carattere speciale (in particolare, un sigillo per le variabili), quindi grep sta ottenendo e cercando solo il $, che è un carattere speciale che significa la fine di una riga. È necessario sia single-citazione è per evitare bash di interpretare il \ ('\$', o aggiungere un altro paio di \\: "\\\$". Presumably, that's where you're getting the \ `da, ma non è necessario che nel sed come è scritto

+0

Poiché "$" è speciale, ha bisogno di tre '\' (ad esempio '\\\') in primo piano? – Village

+1

@Village Non nella sostituzione. – Kevin

2

Non rispondo per sed, le altre risposte sono buone enougth ;-)

È possibile utilizzare less come spettatore a controllare il vostro file enorme (o more, ma less è più comodo di more).

Per la ricerca, è possibile utilizzare fgrep: ignora l'espressione regolare =>fgrep '\$' cercherà davvero il testo \$. fgrep equivale a invocare grep -F.

MODIFICA: fgrep '\$' e fgrep "\$" sono diversi. Nel secondo caso, bash interpreta la stringa e la sostituisce con un singolo carattere: $ (ad esempio, fgrep cerca solo $).

Problemi correlati