Как удалить символы < ASCII из файла?
Удаление не-ASCII-символов в файле
Ответ 1
Если вы хотите использовать Perl, сделайте следующее:
perl -pi -e 's/[^[:ascii:]]//g' filename
Подробное объяснение
Следующее объяснение охватывает каждую часть вышеприведенной команды, предполагая, что читатель не знаком с чем-либо в решении...
-
perl
запустите интерпретатор perl. Perl - это язык программирования, который обычно доступен во всех подобных UNIX системах. Эта команда должна запускаться в командной строке.
-
-p
Флаг
-p
указывает perl на итерацию по каждой строке входного файла, запустите указанные команды (описанные ниже) в каждой строке и затем распечатайте результат. Это эквивалентно завершению вашей программы perl вwhile(<>) { /* program... */; } continue { print; }
. Там есть аналогичный флаг-n
, который делает то же самое, но опускает блокcontinue { print; }
, поэтому вы должны использовать его, если хотите сделать свою собственную печать. -
-i
Флаг
-i
указывает perl, что входной файл должен быть отредактирован на месте, а вывод должен вернуться в этот файл. Это важно для фактического изменения файла. Опускание этого флага будет записывать вывод вSTDOUT
, который затем можно перенаправить на новый файл.Примечание, которую вы не можете опустить
-i
и перенаправитьSTDOUT
во входной файл, так как это будет сжимать входной файл до его чтения. Это то, как работает оболочка и не имеет ничего общего с perl. Флаг-i
работает вокруг этого разумно.Perl и оболочка позволяют объединить несколько одиночных параметров символа в один, поэтому мы можем использовать
-pi
вместо-p -i
Флаг
-i
принимает один аргумент, который является расширением для использования, если вы хотите сделать резервную копию исходного файла, поэтому, если вы использовали-i.bak
, тогда perl скопировал бы входной файл вfilename.bak
перед внесением изменений. В этом примере я опустил создание резервной копии, потому что я ожидаю, что вы все равно будете использовать управление версиями:) -
-e
Флаг
-e
указывает perl, что следующий аргумент - это полная программа perl, инкапсулированная в строку. Это не всегда хорошая идея, если у вас очень длинная программа, так как она может быть нечитаемой, но с помощью одной командной программы, как здесь, ее терпение может улучшить удобочитаемость.Примечание, что мы не можем объединить флаг
-e
с флагом-i
, поскольку оба они принимают один аргумент, и perl предположил бы, что второй флаг является аргументом, например, если мы использовали-ie <program> <filename>
, perl предположил бы, что<program>
и<filename>
являются обоими входными файлами и пытаются создать<program>e
и<filename>e
, предполагая, чтоe
- это расширение, которое вы хотите использовать для резервного копирования, Это не удастся, так как<program>
не является файлом. Другой способ (-ei
) также не работает, поскольку perl попытается выполнитьi
как программу, которая не скомпилирует компиляцию. -
s/.../.../
Это оператор замены на основе regex. Это занимает четыре аргумента. Первое выполняется перед оператором, а если не указано, используется значение по умолчанию
$_
. Второй и третий находятся между символами/
. Четвертый - после окончательного/
и в этом случаеg
.-
$_
В нашем коде первый аргумент$_
, который является переменной цикла по умолчанию в perl. Как уже упоминалось выше, флаг-p
обертывает нашу программу вwhile(<>)
, которая создает циклwhile
, который считывает одну строку за раз (<>
) из ввода. Он неявно назначает эту строку$_
, и все команды, которые принимают один аргумент, будут использовать это, если не указано (например: просто вызовprint;
будет фактически переведен наprint $_;
)). Таким образом, в нашем коде операторs/.../.../
работает один раз в каждой строке входного файла. -
[^[:ascii:]]
Второй аргумент - это шаблон для поиска во входной строке. Этот шаблон является регулярным выражением, поэтому все, заключенное в[]
, является выражением скобки. Этот раздел, вероятно, является самой сложной частью этого примера, поэтому мы подробно обсудим его в конце. -
<empty string>
Третий аргумент - это строка замены, которая в нашем случае является пустой строкой, так как мы хотим удалить все символы, отличные от ascii. -
g
Четвертый аргумент - это флаг модификатора для оператора подстановки. Флагg
указывает, что подстановка должна быть глобальной по всем совпадениям на входе. Без этого флага будет заменен только первый экземпляр. Другими возможными флагами являютсяi
для нечувствительных к регистру совпадений,s
иm
, которые применимы только к многострочным строкам (здесь есть одиночные строки),o
, который указывает, что шаблон должен быть предварительно скомпилирован (что может быть полезно здесь для длинных файлов) иx
, который указывает, что шаблон может включать пробелы и комментарии, чтобы сделать его более читаемым (но мы не должны писать нашу программу на одной строке, если это так).
-
-
filename
Это входной файл, который содержит символы не-ascii, которые мы хотели бы удалить.
[^[:ascii:]]
Итак, теперь обсудим [^[:ascii:]]
более подробно.
Как упоминалось выше, []
в регулярном выражении указывает выражение скобки, которое сообщает движку regex соответствовать одному символу на входе, который соответствует любому из символов в наборе символов внутри выражения. Так, например, [abc]
будет соответствовать либо a
, либо b
или c
, и он будет соответствовать только одному символу. Используя ^
, поскольку первый символ инвертирует совпадение, поэтому [^abc]
будет соответствовать любому одному символу, который не является a
, b
или c
.
Но как насчет [:ascii:]
внутри выражения скобки?
Если у вас установлена система на основе unix, запустите man 7 re_format
в командной строке, чтобы прочитать справочную страницу. Если нет, прочитать онлайн-версию
[:ascii:]
- это класс символов, который представляет весь набор символов ascii
, но этот тип символьного класса может использоваться только внутри выражения скобки. Правильный способ использования этого параметра - [[:ascii:]]
, и он может быть отменен, как в случае с тегом abc
выше, или объединен в выражении скобки с другими символами, поэтому, например, [éç[:ascii:]]
будет соответствовать всем символам ascii, а также é
и ç
, которые не являются ascii, а [^éç[:ascii:]]
будет соответствовать всем символам, которые не являются ascii, а также не é
или ç
.
Ответ 2
tr -dc [:graph:][:cntrl:] < input-file > cleaned-file
Предположим, что вы хотите сохранить "контрольные" символы и "печатные" символы. При необходимости скрипите.
Ответ 3
perl -pe's/[[:^ascii:]]//g' < input.txt > output.txt
Ответ 4
Вы можете написать программу на C следующим образом:
#include <stdio.h>
#include <ctype.h>
int main(int argc, char **argv)
{
FILE *fin = fopen("source_file", "rb");
FILE *fout = fopen("target_file", "w");
int c;
while ((c = fgetc(fin)) != EOF) {
if (isprint(c))
fputc(c, fout);
}
fclose(fin);
fclose(fout);
return 0;
}
Примечание. Для простоты были устранены ошибки.
Скомпилируйте его с помощью
$ gcc -W source_code.c -o convert
Запустите его с помощью
$ ./convert
Ответ 5
Мой два цента: он может не решить вашу проблему, но может дать вам несколько советов.
Команда file
сообщает вам кодировку файла, то есть UTF, ASCII и т.д., и iconv
может преобразовывать файл между различными кодировками.