Подтвердить что ты не робот

Удаление не-ASCII-символов в файле

Как удалить символы < ASCII из файла?

4b9b3361

Ответ 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 может преобразовывать файл между различными кодировками.