Удалите символы неASCII в файле [дубликат]

Этот вопрос уже имеет ответ здесь:

Как я удаляю символы неASCII из файла?

32
задан Peter Mortensen 1 September 2016 в 18:27
поделиться

5 ответов

Если вы хотите использовать 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 и e , предполагая, что 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, а также не é или ç .

59
ответ дан 27 November 2019 в 20:15
поделиться
perl -pe's/[[:^ascii:]]//g' < input.txt > output.txt
5
ответ дан 27 November 2019 в 20:15
поделиться

Вы можете написать программу на языке 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
3
ответ дан 27 November 2019 в 20:15
поделиться
tr -dc [:graph:][:cntrl:] < input-file > cleaned-file

Предполагается, что вы хотите сохранить «управляющие» символы и «печатные» символы. Скрипьте по мере необходимости.

8
ответ дан 27 November 2019 в 20:15
поделиться

Мои два цента : Это может не решить вашу проблему, но может дать вам несколько подсказок.

Команда file сообщает вам кодировку файла, то есть UTF , ASCII и т. Д., А iconv может преобразовывать файл между разными кодировками.

1
ответ дан 27 November 2019 в 20:15
поделиться
Другие вопросы по тегам:

Похожие вопросы: