grep, aby znaleźć pliki zawierające ^ M (powrót karetki Windows)

72

Używam Linuksa. Gdzieś ukryty w tysiącach plików konfiguracyjnych jest nieznośny ^ M (Windows cariage return) i muszę go znaleźć, ponieważ powoduje to awarię serwera.

Jak znaleźć ^ M wśród hierarchii katalogów pełnej plików konfiguracyjnych?

Myślę, że nie mogę wpisać ^ M w linii poleceń bash. Ale mam go w pliku tekstowym, który nazwałem m.txt

Nicolas Raoul
źródło
Powiązane: Usuń znak powrotu karetki w Uniksie .
40XUserNotFound
Windows będzie ^ M ^ J
barlop
3
„Nie mogę wpisać ^ M w linii poleceń bash”. Tak, możesz. Spróbuj control-V Control-M
Hennes

Odpowiedzi:

91
grep -r $'\r' *

Użyj -rdo wyszukiwania rekurencyjnego i $''ucieczki w stylu c w Bash.

Ponadto, jeśli masz pewność, że jest to plik tekstowy, uruchomienie powinno być bezpieczne

tr -d $'\r' < filename

aby usunąć wszystko \rz pliku.

Jeśli używasz GNU sed, -imożesz przeprowadzić edycję w miejscu, więc nie będziesz musiał odpisywać:

sed $'s/\r//' -i filename
livibetter
źródło
10
@Nicolas: Możesz wpisać ^ M w wierszu poleceń, naciskając ^ V ^ M, ale lepiej użyć $'\r'.
Dennis Williamson
Świetnie, działa! Dziękuję też za sztuczkę ^ V ^ M :-)
Nicolas Raoul
5
Pod Cygwin, -U jest potrzebne, aby to zadziałało. I -n powie ci numer linii: grep -r -U -n -e $ '\ r'
Rainer Blome
4
Dodaj -l do polecenia grep, aby po prostu wyświetlić nazwy plików. W przeciwnym razie możesz zostać zbombardowany pasującymi liniami.
Brendan Byrd
1
@uprego nie jestem pewien, czy je teraz rozumiesz, ale fyi i inni szukają $'przeczytania pierwszego trafienia na stronie podręcznika bash(1), w zasadzie widać to tak, jakbyś pisał literał C. Jeśli chodzi o command < filenamekorzystanie z <lub >nazywa przekierowanie , to pierwszy raz widziałem ktoś nazwał go większa ekspresja . Szukaj REDIRECTIONw bash(1).
livibetter
12

Kiedy próbowałem, mogłem stwierdzić, że to trochę działa, ale linie drukowały się puste. Dodaj w opcji:

--color=never

Jeśli dostaniesz ten problem, myślę, że to znaki ucieczki dla podświetlania kolorów przeszkadzają \rpostaci.

Judson Wilson
źródło
2

Jeśli twój serwer nie ma powłoki bash, alternatywą jest użycie tej -fopcji grepw połączeniu z przygotowanym plikiem zawierającym \r.

Aby utworzyć plik:

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

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

Aby przeprowadzić wyszukiwanie

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

lub możesz być trochę leniwy i po prostu wpisz *,

$ grep -f /tmp/cr *

Opcja na jest używany do określenia pliku, który zawiera wzory wszystkich, po jednym w wierszu. W tym przypadku jest tylko jeden wzór.-f filenamegrep

Kiwi Nick
źródło
2

Jeśli dobrze rozumiem twoje pytanie, tak naprawdę chcesz znormalizować wszystkie zakończenia linii do standardu Unix LF ( \x0a). To nie to samo, co zwykłe usuwanie CRs ( \x0d).

Jeśli zdarzy ci się mieć jakieś pliki Mac, w których używa się tylko CR dla nowych linii, zniszczysz te pliki. (Tak, komputery Mac powinny używać LF od prawie 20 lat, ale wciąż istnieje (w 2019 r.) Wiele aplikacji na komputery Mac, które używają tylko CR).

Możesz użyć \R klawisza Escape w Perlu, aby zastąpić dowolny rodzaj nowej linii \n.

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

Spowodowałoby to zastąpienie w miejscu wszelkiego rodzaju podziałów liniowych na \nin $your_file, utrzymując kopię zapasową oryginalnego pliku w ${your_file}.bak.

mivk
źródło
1

Aby użyć grep na znakach końca linii, myślę, że musisz powiedzieć grep, że plik jest binarny.

-l (litera L) służy do drukowania tylko nazwy pliku

-P jest dla wyrażenia regularnego perla (więc \ x0d jest transformowane do \ r lub ^ M)

grep -l --binary -P '\x0d' *
Vouze
źródło
0

Jeśli korzystasz z komputera Mac i używasz homebrew , możesz:

brew install tofrodos
fromdos file.txt

aby usunąć wszystkie zwroty karetki Windows z pliku.txt

Aby wrócić do powrotu karetki systemu Windows,

todos file.txt
kortina
źródło
aby wyszukać w folderze i wyczyścić wszystkie pliki pochodzące z dos, uruchom polecenie: znajdź. -type f -name "* .java" | xargs fromdos
Taiko
0

W stylu wyrażeń regularnych różne znaki nowej linii:

Windows (CR LF)
\r\n

Unix (LF)
\n

Ponieważ \r\nsekwencja jest dość wyjątkowa, myślę, że powinieneś być w stanie jej szukać w ten sposób?

Co gorsza, komputery Mac miały po prostu „\ r” zamiast nowej linii. Nie mogę tego zweryfikować, ale nie sądzę, że generacje MacOSX już to robią.

Starsze komputery Mac (CR)
\r

Jeff Atwood
źródło
W katalogu zawierającym m.txt grep "\r\n" *nie daje żadnego wyniku. Brak wyników dla egrep -e "\r\n" *norgrep -E "\r\n" *
Nicolas Raoul
@nicolas ah, źle zrozumiałem .. miałeś na myśli CR tylko \rmój zły. Pełna linia nowego systemu to rzeczywiście \r\nCRLF
Jeff Atwood
0

Zgodnie z poprzednimi odpowiedziami metoda „tr” jest dobra:

533 $ if [[-n " tr -cd "\r" <~/.bashrc"]]; następnie powtórz „DOS”; w przeciwnym razie echo „UNIX”; fi

UNIX

534 $ if [[-n " tr -cd "\r" <dosfile.txt"]]; następnie powtórz „DOS”; w przeciwnym razie echo „UNIX”; fi

DOS

Malcolm Boekhoff
źródło