Можно ли использовать find
команду, чтобы найти все «недвоичные» файлы в каталоге? Вот проблема, которую я пытаюсь решить.
Я получил архив файлов от пользователя Windows. Этот архив содержит исходный код и файлы изображений. Наша система сборки не очень хорошо работает с файлами, имеющими оконные строки. У меня есть программа командной строки ( flip -u
), которая будет переворачивать окончания строки между * nix и windows. Итак, я хотел бы сделать что-то вроде этого
find . -type f | xargs flip -u
Однако, если эта команда будет запущена для файла образа или другого двоичного медиафайла, файл будет поврежден. Я понимаю, что мог бы составить список расширений файлов и отфильтровать их, но я бы предпочел иметь что-то, что не зависит от меня, поддерживая этот список в актуальном состоянии.
Итак, есть ли способ найти все недвоичные файлы в дереве каталогов? Или я должен рассмотреть альтернативное решение?
file
утилиту где-нибудь в вашем скрипте / конвейере, чтобы определить, является ли файл данными или текстомОтветы:
Я использовал бы
file
и передавал вывод в grep или awk, чтобы найти текстовые файлы, затем извлекал бы только часть имени файлаfile
вывода и передавал ее в xargs.что-то типа:
Обратите внимание, что grep ищет «текст ASCII», а не просто текст - вы, вероятно, не хотите связываться с документами Rich Text, текстовыми файлами Unicode и т. Д.
Вы также можете использовать
find
(или что-то еще) для создания списка файлов для проверкиfile
:-d'\n'
Аргумент xargs делает xargs рассматривать каждую входную линию в качестве отдельного аргумента, таким образом , питания для имен файлов с пробелами и другими проблемными символами. то есть это альтернатива тому,xargs -0
когда входной источник не генерирует или не может генерировать NULL-разделенный вывод (например, параметрfind
's'-print0
). Согласно журналу изменений, xargs получил опцию-d
/--delimiter
в сентябре 2005 года, поэтому должен быть в любом не древнем дистрибутиве Linux (я не был уверен, поэтому я проверил - я просто смутно вспомнил, что это было «недавнее» дополнение).Обратите внимание, что перевод строки является допустимым символом в именах файлов, поэтому он будет прерываться, если в именах файлов есть переводы строк. Для обычных пользователей Unix это патологически безумно, но не случайно, если файлы были созданы на компьютерах Mac или Windows.
Также обратите внимание, что
file
не идеально. Это очень хорошо для определения типа данных в файле, но иногда может запутаться.Я использовал многочисленные вариации этого метода много раз в прошлом с успехом.
источник
file
отображается,English text
а неASCII text
в моей системе Solaris, поэтому я изменил эту часть соответственно. Также я заменилawk -F: '{print $1}'
на аналогcut -f1 -d:
.grep -I
фильтры бинарных файловtext
должен быть достаточным. Это также подберетfile
описания какASCII Java program text
илиHTML document text
илиtroff or preprocessor input text
.ASCII text
чтобы избежать путаницы RTF.Нет. В двоичном или недвоичном файле нет ничего особенного. Вы можете использовать эвристику, например, «содержит только символы в 0x01–0x7F», но это будет вызывать текстовые файлы с двоичными файлами не-символов ASCII и текстовые файлы с незадачливыми двоичными файлами.
Теперь, когда вы проигнорировали это ...
почтовые файлы
Если он поступает от пользователя Windows в виде zip-файла, формат zip поддерживает маркировку файлов как двоичных, так и текстовых в самом архиве. Вы можете использовать
-a
опцию unzip, чтобы обратить на это внимание и конвертировать. Конечно, см. Первый абзац, почему это может быть не очень хорошей идеей (программа zip, возможно, догадалась неправильно, когда создавала архив).zipinfo сообщит вам, какие файлы являются двоичными (b) или текстовыми (t) в списке zipfile.
другие файлы
Команда file проверит файл и попытается его идентифицировать. В частности, вы, вероятно, найдете его
-i
(выходной тип MIME) полезным; конвертировать только файлы с типом текста / *источник
Общее решение для обработки только недвоичных файлов с
bash
использованиемfile -b --mime-encoding
:Я связался с автором файловой утилиты, и он добавил изящный
-00
параметр в версии 5.26 (выпущена 2016-04-16, например, в текущих версиях Arch и Ubuntu 16.10), которая печатает сразуfile\0result\0
для нескольких файлов, поданных в нее, таким образом, вы можете сделать это например:(
awk
Часть состоит в том, чтобы отфильтровать каждый файл, который не является двоичным.ORS
Это разделитель вывода.)Может также использоваться в цикле:
Основываясь на этом и предыдущем, я создал небольшой
bash
скрипт для фильтрации двоичных файлов, который использует новый метод с использованием-00
параметраfile
в более новых его версиях и возвращается к предыдущему методу в более старых версиях:Или здесь более POSIX-у, но он требует поддержки
sort -V
:источник
Принятый ответ не нашел их всех для меня. Вот пример использования grep
-I
для игнорирования двоичных файлов и игнорирования всех скрытых файлов ...Вот он используется в практическом применении: dos2unix
https://unix.stackexchange.com/a/365679/112190
источник
Ответ Кас хороший, но он предполагает вменяемые имена файлов; в частности предполагается, что имена файлов не будут содержать переводы строки.
Здесь нет веских оснований для такого предположения, поскольку довольно просто (и, на мой взгляд, более чисто) правильно обрабатывать этот случай:
Команда использует
find
только функции, указанные в POSIX . Использование-exec
для запуска произвольных команд в качестве логических тестов является простым, надежным (корректно обрабатывает нечетные имена файлов) и более переносимым, чем-print0
.Фактически, все части команды определены POSIX, кроме
flip
.Обратите внимание, что
file
это не гарантирует точности результатов, которые он возвращает. Однако на практике поиск текста «ASCII» в его выводе достаточно надежен.(Возможно, он может пропустить некоторые текстовые файлы, но очень маловероятно, чтобы неправильно идентифицировать двоичный файл как «текст ASCII» и исказить его - поэтому мы ошибаемся из-за осторожности.)
источник
calls
может быть довольно медленным, например, для видео он расскажет вам все о кодировке.-
.file
, он может принимать несколько файлов в качестве аргументов.find
команда будет иметь префикс./
перед любым именем файла, передаваемым команде оболочки; (3) Использованиеgrep
в качестве теста дляfile
вывода одной команды за раз - единственный способ POSIX, который я вижу, чтобы гарантировать правильную обработку имен файлов, которые могут содержать переводы строки.file
поддерживает--mime-encoding
флаг и--
разделитель, ни одно из которых не гарантируется POSIX .Это найдет все обычные файлы (
-type f
) в текущем каталоге (или ниже), которыеgrep
считают , что они не пустые и не двоичные.Используется
grep -I
для различения двоичных и недвоичных файлов.-I
Флаг и приведетgrep
к выходу со статусом ненулевым , когда он обнаруживает , что файл является двоичным. «Двоичный» файл - это, в соответствии сgrep
файлом, который содержит символ вне диапазона ASCII для печати.-q
Вариантgrep
заставит его выйти со статусом нулевого выхода , если данный шаблон найден, без выделения каких - либо данных. Шаблон, который мы используем, представляет собой одну точку, которая будет соответствовать любому символу.Если файл не двоичный и содержит хотя бы один символ, печатается имя файла.
Если вы чувствуете себя смелым, вы также можете подключиться
flip -u
к нему:источник
Попробуй это :
Если аргумент
grep '[^ -~]'
IS'[^<tab><space>-~]'
.Если вы вводите его в командной строке оболочки, введите Ctrl+ Vперед Tab. В редакторе не должно быть проблем.
'[^<tab><space>-~]'
будет соответствовать любому символу, который не является текстом ASCII (возврат каретки игнорируетсяgrep
).-L
будет печатать только имя файла файлов, которые не совпадают-Z
выведет имена файлов, разделенные нулевым символом (дляxargs -0
)источник
grep -P
(если доступно)\t
доступно. В качестве альтернативы можно использовать перевод локали, если оболочка его поддерживает:$'\t'
(bash
иzsh
делать).Альтернативное решение:
Команда dos2unix преобразует окончания строк из Windows CRLF в Unix LF и автоматически пропускает двоичные файлы. Я применяю это рекурсивно, используя:
источник
dos2unix
качестве аргумента можно использовать несколько имен файлов, это гораздо эффективнееfind . -type f -exec dos2unix {} +
sudo find / (-type f -and -path '* / git / *' -iname 'README') -exec grep -liI '100644 \ | 100755' {} \; -exec flip -u {} \;
i. (-type f -and -path '* / git / *' -iname 'README'): поиск файлов по пути, содержащему имя git и файл с именем README. Если вы знаете какую-либо конкретную папку и имя файла для поиска, будет полезно.
Команда ii.-exec запускает команду для имени файла, сгенерированного командой find
III. \; указывает на конец команды
iv. {} - это вывод файла / имя_фолдера, найденного в предыдущем поиске поиска
v. Несколько команд могут быть запущены впоследствии. Добавив -exec "команда" \; например, с помощью -exec flip -u \;
vii.grep
Вы можете клонировать этот тестовый каталог и попробовать его: https://github.com/alphaCTzo7G/stackexchange/tree/master/linux/findSolution204092017
более подробный ответ здесь: https://github.com/alphaCTzo7G/stackexchange/blob/master/linux/findSolution204092017/README.md
источник