grep per trovare file che contengono ^ M (ritorno a capo di Windows)


72

Io uso Linux. Esiste un fastidioso ^ M (Windows Cariage Return) da qualche parte nascosto in migliaia di file di configurazione, e devo trovarlo, perché fa fallire il server.

Come trovo ^ M in una gerarchia di directory piena di file di configurazione?

Penso di non poter inserire ^ M dalla riga di comando bash. Ma ce l'ho in un file di testo che ho chiamato m.txt



windows sarebbe ^ M ^ J
barlop

3
"Non riesco a inserire ^ M nella riga di comando bash". Si, puoi. Prova control-V Control-M
Hennes il

Risposte:


92
grep -r $'\r' *

Utilizzare -rper la ricerca ricorsiva e $''per la fuga in stile c in Bash.

Inoltre, se sei sicuro che sia un file di testo, allora dovrebbe essere sicuro da eseguire

tr -d $'\r' < filename

per rimuovere tutto \rin un file.

Se usi GNU sed, -ipuoi eseguire modifiche sul posto, quindi non dovrai riscrivere:

sed $'s/\r//' -i filename

10
@Nicolas: puoi inserire un ^ M dalla riga di comando premendo ^ V ^ M, ma è meglio usarlo $'\r'.
Dennis Williamson,

Ottimo, funziona! Grazie anche per il trucco ^ V ^ M :-)
Nicolas Raoul,

5
Sotto Cygwin, -U è necessario per farlo funzionare. E -n ti dirà il numero di riga: grep -r -U -n -e $ '\ r'
Rainer Blome

4
Aggiungi un -l al comando grep per visualizzare solo i nomi dei file. Altrimenti potresti essere bombardato da linee corrispondenti.
Brendan Byrd,

1
@uprego non sono sicuro di capirli ora, ma Fyi e altri, cerca di $'leggere il primo hit nella manpage bash(1), in sostanza, puoi vederlo come se stessi scrivendo una stringa letterale C. Per quanto riguarda command < filename, l'uso di <o >si chiama reindirizzamento , questa è la prima volta che vedo qualcuno chiamarlo espressione maggiore . Cerca REDIRECTIONin bash(1).
livibetter,

12

Quando ho provato, ho capito che funzionava in qualche modo, ma le linee erano vuote. Aggiungi nell'opzione:

--color=never

Se riscontri questo problema, penso che siano i caratteri di escape per l'evidenziazione dei colori che interferiscono con il \rpersonaggio.


2

Se il tuo server non ha una shell bash, un'alternativa è usare l' -fopzione on grep, in combinazione con un file preparato contenente \r.

Per creare il file:

$ echo -ne '\r' > /tmp/cr                    --or--                   $ printf '\r' > /tmp/cr

$ od -c /tmp/cr
0000000  \r
0000001

Per fare effettivamente la ricerca

$ grep -f /tmp/cr *.html *.php *.asp *.whatever

oppure puoi essere un po 'pigro e digitare *,

$ grep -f /tmp/cr *

L' opzione on viene utilizzata per specificare un file che contiene motivi da abbinare, uno per riga. In questo caso c'è solo un modello.-f filenamegrep


2

Se capisco correttamente la tua domanda, quello che vuoi veramente è normalizzare tutti i finali di linea allo \x0astandard Unix LF ( ). Ciò non equivale a rimuovere CRs alla cieca ( \x0d).

Se ti capita di avere dei file Mac intorno ai quali usi solo CR per le nuove righe, distruggerai quei file. (Sì, i Mac dovrebbero usare LF da quasi 20 anni, ma ci sono ancora (nel 2019) molte app Mac che usano solo CR).

È possibile utilizzare l' \R uscita di interruzione di riga di Perl per sostituire qualsiasi tipo di newline con \n.

perl -i.bak -pe 's/\R/\n/g' $your_file

Ciò sostituirà sul posto qualsiasi tipo di interruzione di riga con \nin $your_file, mantenendo un backup del file originale in ${your_file}.bak.


1

Per usare grep sui caratteri di fine riga, suppongo che tu debba dire a grep che il file è binario.

-l (lettera L) serve per stampare solo il nome file

-P è per perge regexp (quindi \ x0d viene trasformato in \ r o ^ M)

grep -l --binary -P '\x0d' *

0

Se sei su un Mac e usi l' homebrew , puoi fare:

brew install tofrodos
fromdos file.txt

per rimuovere tutti i ritorni a capo di Windows da file.txt

Per tornare ai ritorni a capo di Windows,

todos file.txt

per cercare in una cartella e pulire tutti i file provenienti da dos, eseguire questo comando: find. -type f -name "* .java" | xargs fromdos
Taiko,

0

In stile di espressione regolare, varie nuove linee:

Windows (CR LF)
\r\n

Unix (LF)
\n

Dal momento che la \r\nsequenza è abbastanza unica, penso che dovresti essere in grado di cercarla in quel modo?

A peggiorare le cose, i Mac avevano solo '\ r' al posto di newline. Non posso verificarlo, ma non credo che le generazioni MacOSX lo facciano più.

Mac precedenti (CR)
\r


Nella directory che contiene m.txt, grep "\r\n" *non fornisce alcun risultato. Nessun risultato né per egrep -e "\r\n" *grep -E "\r\n" *
Nicolas Raoul,

@nicolas ah, ho capito male .. intendevi solo CR \rmio male. Una newline full windows è davvero \r\no CRLF
Jeff Atwood,

0

Seguendo le risposte precedenti, il metodo 'tr' è buono:

533 $ if [[-n " tr -cd "\r" <~/.bashrc"]]; quindi echo "DOS"; else echo "UNIX"; fi

UNIX

534 $ if [[-n " tr -cd "\r" <dosfile.txt"]]; quindi echo "DOS"; else echo "UNIX"; fi

DOS

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.