Как найти файлы формата dos в файловой системе Linux

Я хотел бы узнать, какие из моих файлов в каталоге представляют собой текстовые файлы dos (в отличие от текстовых файлов unix).

Что я пробовал:

find . -name "*.php" | xargs grep ^M -l

Это не дает мне надежных результатов... поэтому я ищу лучшую альтернативу.

Любые предложения, идеи?

Спасибо

Разъяснение

В дополнение к тому, что я сказал выше, проблема в том, что у меня есть куча файлов dos, в которых нет символов ^ M (отсюда и моя заметка о надежности).

Способ, которым я сейчас определяю, является ли файл dos или нет через Vim, где внизу он говорит:

"filename.php" [dos] [noeol]

Ответ 1

Не уверен, что вы подразумеваете под "ненадежностью", но вы можете попробовать:

find . -name '*.php' -print0 | xargs -0 grep -l '^M$'

Это использует более жестокие имена файлов-с-в-в-дружественных и только находит возврат каретки непосредственно перед концом строки.

Имейте в виду, что ^M - это один символ CTRL M, а не два символа.

И также, что он будет перечислять файлы, в которых даже одна строка находится в режиме DOS, что, вероятно, так и должно быть, так как это были бы файлы UNIX, искаженные не-UNIX-редактором.


Основываясь на вашем обновлении, vim сообщает ваши файлы как формат DOS:

Если vim сообщает об этом в формате DOS, каждая строка заканчивается на CRLF. Это то, как работает vim. Если даже одна строка не имеет CR, то она считается UNIX-форматом, а символы ^M видны в буфере. Если весь формат DOS, символы ^M не отображаются:

Vim будет искать окончание строк dos и unix, но Vim имеет встроенное предпочтение для unix-формата.

- Если все строки в файле заканчиваются CRLF, будет применяться формат файла dos, что означает, что каждый CRLF удаляется при чтении строк в буфер, а опция buffer ff - dos.
- Если одна или несколько строк заканчиваются только LF, будет применен формат файла unix, что означает, что каждый LF будет удален (но каждый CR будет присутствовать в буфере и будет отображаться как ^ M), а буфер 'ff' опция будет unix.

Если вы действительно хотите знать, что в файле, не полагайтесь на слишком умный инструмент, например vim: -)

Использование:

od -xcb input_file_name | less

и проверьте окончание строки.

Ответ 2

Как насчет:

find . -name "*.php" | xargs file | grep "CRLF"

Я не думаю, что можно попробовать и использовать ^M, чтобы попытаться найти файлы.

Ответ 3

Это похоже на ваше оригинальное решение; поэтому, возможно, вам будет легче запомнить:

find . -name "*.php" | xargs grep "\r" -l

Процесс мышления:

В VIM, чтобы удалить ^ M, вы набираете:

 %s:/^M//g

Где ^ - ваша клавиша Ctrl, а M - клавиша ENTER. Но я никогда не мог вспомнить ключи, чтобы напечатать эту последовательность, поэтому я всегда удалял их, используя:

 %s:/\r//g

Таким образом, мой вывод состоит в том, что \r и ^ M эквивалентны, причем первое легче запомнить для ввода.

Ответ 4

Мне повезло с

find . -name "*.php" -exec grep -Pl "\r" {} \;

Ответ 5

Найти GNU

find . -type f -iname "*.php"  -exec file "{}" + | grep CRLF

Я не знаю, что вы хотите сделать после того, как найдете эти файлы php DOS, но если вы хотите преобразовать их в формат unix, то

find . -type f -iname "*.php"  -exec dos2unix "{}" +;

будет достаточно. Нет необходимости конкретно проверять, являются ли они файлами DOS или нет.

Ответ 6

Если вы предпочитаете, чтобы vim сообщал вам, какие файлы находятся в этом формате, вы можете использовать следующий script:

"use this script to check which files are in dos format according to vim
"use: in the folder that you want to check
"create a file, say res.txt
"> vim -u NONE --noplugins res.txt
"> in vim: source this_script.vim

python << EOF
import os
import vim

cur_buf =  vim.current.buffer

IGNORE_START = ''.split()
IGNORE_END = '.pyc .swp .png ~'.split()

IGNORE_DIRS = '.hg .git dd_ .bzr'.split()

for dirpath, dirnames, fnames in os.walk(os.curdir):
  for dirn in dirnames:
    for diri in IGNORE_DIRS:
      if dirn.endswith(diri):
        dirnames.remove(dirn)
        break
  for fname in fnames:
    skip = False
    for fstart in IGNORE_START:
      if fname.startswith(fstart):
        skip = True
    for fend in IGNORE_END:
      if fname.endswith(fend):
        skip = True
    if skip is True:
      continue
    fname = os.path.join(dirpath, fname)
    vim.command('view {}'.format(fname))
    curr_ff = vim.eval('&ff')
    if vim.current.buffer != cur_buf:
      vim.command('bw!')
    if curr_ff == 'dos':
      cur_buf.append('{} {}'.format(curr_ff, fname))
EOF

ваш vim должен быть скомпилирован с помощью python (python используется для перебора файлов в папке, возможно, это более простой способ сделать это, но я этого не знаю...

Ответ 7

Если ваша команда dos2unix имеет -i, вы можете использовать эту функцию для поиска файлов в каталоге, в котором есть разрывы строк DOS.

$ man dos2unix
.
.
.
     -i[FLAGS], --info[=FLAGS] FILE ...
           Display file information. No conversion is done.

    The following information is printed, in this order:
    number of DOS line breaks,
    number of Unix line breaks,
    number of Mac line breaks,
    byte order mark,
    text or binary, file name.
.
.
.
Optionally extra flags can be set to change the (-i) output.
.
.
.
           c   Print only the files that would be converted.

Следующий однострочный скрипт читает:

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

$ find. -type f | xargs -d '\n' dos2unix -ic | xargs -d '\n' dos2unix