grep, чтобы найти файлы, содержащие ^ M (возврат каретки Windows)


72

Я использую Linux. Где-то спрятано ^ M (возвращение кариеса Windows) где-то в тысячах файлов конфигурации, и я должен найти его, потому что это приводит к сбою сервера.

Как найти ^ M среди иерархии каталогов, полной конфигурационных файлов?

Я думаю, что я не могу ввести ^ M в командной строке bash. Но у меня есть это в текстовом файле, который я назвал m.txt



окна будут ^ M ^ J
15:35

3
Msgstr "Я не могу ввести ^ M в командной строке bash". Да, ты можешь. Попробуйте Control-V Control-M
Hennes

Ответы:


92
grep -r $'\r' *

Используется -rдля рекурсивного поиска и $''для выхода в стиле c в Bash.

Более того, если вы уверены, что это текстовый файл, то он должен быть безопасным для запуска

tr -d $'\r' < filename

удалить все \rв файле.

Если вы используете GNU sed, -iможете выполнять редактирование на месте, поэтому вам не нужно писать обратно:

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

10
@Nicolas: Вы можете ввести ^ M в командной строке, нажав ^ V ^ M, но лучше использовать $'\r'.
Деннис Уильямсон

Отлично, это работает! Спасибо за трюк ^ V ^ M :-)
Николас Рауль

5
Под Cygwin, -U необходим, чтобы сделать эту работу. И -n сообщит вам номер строки: grep -r -U -n -e $ '\ r'
Rainer Blome

4
Добавьте -l к команде grep, чтобы просто просмотреть имена файлов. В противном случае вы можете быть засыпаны соответствующими линиями.
Брендан Берд

1
@uprego не уверен, что вы понимаете их сейчас, но fyi и другие, поиск $'прочитал первый хит на man-странице bash(1), в основном, вы можете видеть это так, как если бы вы писали буквенную строку C. Что касается command < filenameиспользования <или >называется перенаправлением , я впервые увидел, что кто-то назвал это более выражением . Поиск REDIRECTIONв bash(1).
Livibetter

12

Когда я пытался, я мог сказать, что это вроде как работает, но строки печатались пустыми. Добавьте в опцию:

--color=never

Если у вас возникла эта проблема, я думаю, что это экранирующие символы для выделения цвета, мешающие \rперсонажу.


2

Если на вашем сервере нет оболочки bash, альтернативой является использование -fопции on grepв сочетании с подготовленным файлом, содержащим \r.

Чтобы создать файл:

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

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

На самом деле сделать поиск

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

или вы можете быть немного ленивым и просто набрать *,

$ grep -f /tmp/cr *

Вариант на используется , чтобы указать файл, содержащий шаблоны , чтобы соответствовать, по одному в каждой строке. В этом случае есть только один шаблон.-f filenamegrep


2

Если я правильно понимаю ваш вопрос, то вы действительно хотите нормализовать все окончания строк в стандарте Unix LF ( \x0a). Это не то же самое, что просто слепое удаление CR ( \x0d).

Если у вас есть несколько файлов Mac, которые используют только CR для перевода строки, вы уничтожите эти файлы. (Да, Mac должны использовать LF почти 20 лет, но все еще (в 2019 году) есть много приложений Mac, которые используют только CR).

Вы можете использовать перевод \R строки Perl для замены любого вида новой строки \n.

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

Это заменит на месте любой перевод строки на \nin $your_file, сохраняя резервную копию исходного файла в ${your_file}.bak.


1

Чтобы использовать grep для символов конца строки, я думаю, вы должны указать grep, что файл является двоичным.

-l (буква L) предназначена для печати только имени файла

-P для регулярного выражения perl (поэтому \ x0d преобразуется в \ r или ^ M)

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

0

Если вы работаете на Mac и используете homebrew , вы можете сделать:

brew install tofrodos
fromdos file.txt

удалить все возвраты каретки Windows из файла file.txt

Чтобы вернуться к возврату каретки Windows,

todos file.txt

для поиска в папке и очистки всех файлов, поступающих из DOS, выполните команду: find. -тип f -name "* .java" | xargs fromdos
Тайко

0

В стиле регулярных выражений, различные новые строки:

Windows (CR LF)
\r\n

Unix (LF)
\n

Так как \r\nпоследовательность довольно уникальна, я думаю, вы сможете найти ее таким образом?

Что еще хуже, на Маках раньше был символ «\ r» вместо новой строки. Я не могу проверить это, но я не думаю, что поколения MacOSX делают это больше.

Старые Маки (CR)
\r


В каталоге, который содержит m.txt, grep "\r\n" *ничего не дает. Нет результата ни за , egrep -e "\r\n" *ниgrep -E "\r\n" *
Николя Raoul

@ nikolas ах, я неправильно понял .. ты имел в виду CR только \rмой плохой. Полный перевод строки действительно \r\nили CRLF
Джефф Этвуд

0

Следуя предыдущим ответам, метод 'tr' хорош:

533 $ if [[-n " tr -cd "\r" <~/.bashrc"]]; затем эхо "DOS"; еще эхо "UNIX"; фи

UNIX

534 $ if [[-n " tr -cd "\r" <dosfile.txt"]]; затем эхо "DOS"; еще эхо "UNIX"; фи

DOS

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.