Этот вопрос уже имеет ответ здесь:
Как я удаляю символы неASCII из файла?
Если вы хотите использовать Perl, сделайте это следующим образом:
perl -pi -e 's/[^[:ascii:]]//g' filename
Подробное объяснение
Следующее объяснение охватывает каждую часть приведенной выше команды, предполагая, что читатель не знаком с чем-либо в решении ...
perl
запускает интерпретатор perl. Perl - это язык программирования, который обычно доступен во всех unix-подобных системах. Эту команду нужно запускать в приглашении оболочки.
-p
Флаг -p
указывает Perl перебирать каждую строку входного файла, запускать указанные команды (описанные ниже) в каждой строке и затем распечатывать результат. Это эквивалентно заключению вашей программы на Perl в while (<>) {/ * program ... * /; } продолжить {печать; }
. Есть аналогичный флаг -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 <программа> <имя файла>
, perl предположил бы, что <программа>
и <имя файла>
являются оба входных файла и попробуйте создать
и
, предполагая, что e
- это расширение, которое вы хотите использовать для резервного копирования. Это не удастся, поскольку <программа>
на самом деле не является файлом. Другой способ ( -ei
) также не будет работать, поскольку perl попытается выполнить i
как программу, что приведет к сбою компиляции.
s /.../.../
Это оператор подстановки на основе регулярных выражений Perl. Требуется четыре аргумента. Первый идет перед оператором и, если не указан, использует значение по умолчанию $ _
. Второй и третий находятся между символами /
. Четвертый идет после окончательного /
и в данном случае равен g
.
$ _
В нашем коде первым аргументом является $ _
, который является переменной цикла по умолчанию в perl. Как упоминалось выше, флаг -p
оборачивает нашу программу в while (<>)
, который создает цикл while
, который читает по одной строке за раз ( <>
) с входа.Он неявно присваивает эту строку $ _
, и все команды, которые принимают один аргумент, будут использовать это, если не указано иное (например: простой вызов print;
фактически преобразуется в напечатать $ _;
). Итак, в нашем коде оператор s /.../.../
работает один раз с каждой строкой входного файла.
[^ [: ascii:]]
Второй аргумент - это шаблон для поиска во входной строке. Этот шаблон является регулярным выражением, поэтому все, что заключено в []
, является выражением в квадратных скобках. Этот раздел, вероятно, является самой сложной частью этого примера, поэтому мы обсудим его подробно в конце.
<пустая строка>
Третий аргумент - это строка замены, которая в нашем случае является пустой строкой, поскольку мы хотим удалить все символы, отличные от ascii.
g
Четвертый аргумент - это флаг-модификатор для оператора подстановки. Флаг g
указывает, что подстановка должна быть глобальной для всех совпадений во входных данных. Без этого флага будет заменен только первый экземпляр. Другие возможные флаги: i
для совпадений без учета регистра, s
и m
, которые актуальны только для многострочных строк (здесь у нас есть однострочные строки), o
, который указывает, что шаблон должен быть предварительно скомпилирован (что может быть полезно здесь для длинных файлов), и x
, который указывает, что шаблон может включать пробелы и комментарии, чтобы сделать его более читаемым (но мы не должны писать нашу программу в одной строке, если это так).
filename
Это входной файл, содержащий символы, отличные от ascii, которые мы хотели бы исключить.
[^ [: ascii:]]
Итак, теперь давайте обсудим [^ [: ascii:]]
более подробно.
Как упоминалось выше, []
в регулярном выражении определяет выражение в квадратных скобках, которое указывает механизму регулярных выражений сопоставить один символ во входных данных, который соответствует любому из символов в наборе символов внутри выражения. Так, например, [abc]
будет соответствовать либо a
, либо b
, либо c
, и будет соответствовать только одиночный персонаж.Использование ^
в качестве первого символа инвертирует совпадение, поэтому [^ abc]
будет соответствовать любому символу, который не является a
, b
или c
.
Но как насчет [: ascii:]
внутри выражения в квадратных скобках?
Если у вас есть доступная система на базе unix, запустите man 7 re_format
в командной строке, чтобы прочитать страницу руководства. Если нет, прочтите онлайн-версию
[: ascii:]
- это класс символов, который представляет весь набор символов ascii
, но этот тип класса символов может использоваться только внутри выражения в квадратных скобках. Правильный способ использования - [[: ascii:]]
, и он может быть отменен, как в случае abc
выше, или объединен в скобках с другими символами, так что для Например, [éç [: ascii:]]
будет соответствовать всем символам ascii, а также é
и ç
, которые не являются ascii, и [^ éç [: ascii:]]
будет соответствовать всем символам, которые не являются ascii, а также не é
или ç
.
perl -pe's/[[:^ascii:]]//g' < input.txt > output.txt
Вы можете написать программу на языке 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
tr -dc [:graph:][:cntrl:] < input-file > cleaned-file
Предполагается, что вы хотите сохранить «управляющие» символы и «печатные» символы. Скрипьте по мере необходимости.
Мои два цента : Это может не решить вашу проблему, но может дать вам несколько подсказок.
Команда file
сообщает вам кодировку файла, то есть UTF , ASCII и т. Д., А iconv
может преобразовывать файл между разными кодировками.