Как сделать так, чтобы все мои исходные файлы оставались в UTF-8 с окончанием строки Unix?
Я ищу некоторые инструменты командной строки для Linux, которые могут помочь мне обнаружить и преобразовать файлы из наборов символов, таких как iso-8859-1 и windows-1252, в utf-8 и из концов строк Windows в конец строк Unix.
Причина, по которой мне это нужно, заключается в том, что я работаю над проектами на серверах Linux через SFTP с редакторами в Windows (например, Sublime Text), которые просто постоянно портят эти вещи. Прямо сейчас я предполагаю, что примерно половина моих файлов - это utf-8, остальные - iso-8859-1 и windows-1252, так как кажется, что Sublime Text просто выбирает набор символов, который содержит символы, содержащиеся в файле, когда я его сохраняю. Окончания строк ВСЕГДА заканчиваются на конец строки Windows, хотя в опциях я указывал, что окончания строк по умолчанию - LF, поэтому примерно половина моих файлов имеет LF, а половина - CRLF.
Поэтому мне понадобится по крайней мере инструмент, который будет рекурсивно сканировать папку моего проекта и предупреждать меня о файлах, которые отличаются от utf-8 с окончаниями строк LF, чтобы я мог вручную исправить это, прежде чем вносить свои изменения в GIT.
Любые комментарии и личный опыт по теме также приветствуются.
Спасибо
Изменить: у меня есть временное решение в месте, где я использую tree
а также file
выводить информацию о каждом файле в моем проекте, но это довольно сложно. Если я не включу -i
вариант для file
затем многие из моих файлов получают различный вывод, например, текст программы ASCII C++, текст документа HTML, текст на английском языке и т. д.
$ tree -f -i -a -I node_modules --noreport -n | файл xargs | каталог grep -v./config.json: текст программы ASCII C++./debugserver.sh: текст ASCII./.gitignore: текст ASCII, без разделителей строк./lib/config.js: текст ASCII./lib/database.js: текст ASCII./lib/get_input.js: текст ASCII./lib/models/stream.js: ASCII текст на английском языке./lib/serverconfig.js: текст ASCII./lib/server.js: текст ASCII./package.json: текст ASCII./public/index.html: текст документа HTML./src/config.coffee: ASCII текст на английском языке./src/database.coffee: ASCII текст на английском языке./src/get_input.coffee: текст на английском языке ASCII, с ограничителями строки CRLF./src/jtv.coffee: ASCII текст на английском языке./src/models/stream.coffee: ASCII текст на английском языке./src/server.coffee: текст ASCII./src/serverconfig.coffee: текст ASCII./testserver.sh: текст ASCII./vendor/minify.json.js: текст программы ASCII C++ с разделителями строк CRLF
Но если я включу -i
это не показывает мне терминаторы строки:
$ tree -f -i -a -I node_modules --noreport -n | файл xargs -i | каталог grep -v./config.json: text/x-C++; Charset= US-ASCII./debugserver.sh: text/plain; Charset= US-ASCII./.gitignore: text/plain; Charset= US-ASCII./lib/config.js: text/plain; Charset= US-ASCII./lib/database.js: text/plain; Charset= US-ASCII./lib/get_input.js: text/plain; Charset= US-ASCII./lib/models/stream.js: text/plain; Charset= US-ASCII./lib/serverconfig.js: text/plain; Charset= US-ASCII./lib/server.js: text/plain; Charset= US-ASCII./package.json: text/plain; Charset= US-ASCII./public/index.html: text/html; Charset= US-ASCII./src/config.coffee: text/plain; Charset= US-ASCII./src/database.coffee: text/plain; Charset= US-ASCII./src/get_input.coffee: text/plain; Charset= US-ASCII./src/jtv.coffee: text/plain; Charset= US-ASCII./src/models/stream.coffee: text/plain; Charset= US-ASCII./src/server.coffee: text/plain; Charset= US-ASCII./src/serverconfig.coffee: text/plain; Charset= US-ASCII./testserver.sh: text/plain; Charset= US-ASCII./vendor/minify.json.js: text/x-C++; Charset= US-ASCII
Кроме того, почему он отображает charset=us-ascii, а не utf-8? А что такое текст / х-с ++? Есть ли способ вывести только charset=utf-8
а также line-terminators=LF
для каждого файла?
3 ответа
Решение, которое я выбрал, - это два плагина Sublime Text 2 "EncodingHelper" и "LineEndings". Теперь я получаю как кодировку файла, так и окончание строк в строке состояния:
Если кодировка неправильная, я могу File-> Save with Encoding. Если окончания строк неправильные, последний плагин поставляется с командами для изменения концов строк:
Если файл не имеет спецификации и "интересных символов" в объеме текста, который file
смотрит на, file
приходит к выводу, что это ASCII ISO-646 - строгое подмножество UTF-8. Вы можете обнаружить, что размещение спецификаций на всех ваших файлах стимулирует работу всех этих инструментов Windows; условное обозначение спецификации файла UTF-8, созданное в Windows. Или это может ухудшить ситуацию. Что касается х / с ++, то это просто file
пытаюсь быть полезным и терпит неудачу. В вашем javascript есть что-то похожее на C++.
Apache Tika имеет детектор кодирования; вы могли бы даже использовать драйвер командной строки, который поставляется с ним в качестве альтернативы file
, Он будет придерживаться типов MIME, а не переходить на C++.
Вместо file
Попробуйте пользовательскую программу, чтобы проверить только то, что вы хотите. Вот быстрый взлом, в основном на основе некоторых хитов Google, которые были случайно написаны @ikegami.
#!/usr/bin/perl
use strict;
use warnings;
use Encode qw( decode );
use vars (qw(@ARGV));
@ARGV > 0 or die "Usage: $0 files ...\n";
for my $filename (@ARGV)
{
my $terminator = 'CRLF';
my $charset = 'UTF-8';
local $/;
undef $/;
my $file;
if (open (F, "<", $filename))
{
$file = <F>;
close F;
# Don't print bogus data e.g. for directories
unless (defined $file)
{
warn "$0: Skipping $filename: $!\n;
next;
}
}
else
{
warn "$0: Could not open $filename: $!\n";
next;
}
my $have_crlf = ($file =~ /\r\n/);
my $have_cr = ($file =~ /\r(?!\n)/);
my $have_lf = ($file =~ /(?!\r\n).\n/);
my $sum = $have_crlf + $have_cr + $have_lf;
if ($sum == 0)
{
$terminator = "no";
}
elsif ($sum > 2)
{
$terminator = "mixed";
}
elsif ($have_cr)
{
$terminator = "CR";
}
elsif ($have_lf)
{
$terminator = "LF";
}
$charset = 'ASCII' unless ($file =~ /[^\000-\177]/);
$charset = 'unknown'
unless eval { decode('UTF-8', $file, Encode::FB_CROAK); 1 };
print "$filename: charset $charset, $terminator line endings\n";
}
Обратите внимание, что это не имеет понятия о устаревших 8-битных кодировках - просто unknown
если это ни чистый 7-битный ASCII, ни правильный UTF-8.