Как найти файлы формата 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