2010-07-16 2 views

ответ

56

Если вы хотите использовать 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

    The -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/.../.../

    Это регулярное выражение основано оператор замены Perl. Это занимает четыре аргумента. Первый - перед оператором, а если не указан, используется значение по умолчанию $_. Второе и третье - между символами . Четвертый - после окончательного / и g в этом случае.

    • $_ В нашем коде, первый аргумент $_ который является переменная цикла по умолчанию в Perl. Как упоминалось выше, флаг -p обертывает нашу программу в while(<>), которая создает цикл while, который считывает по одной строке за один раз (<>) со входа. Он неявно назначает эту строку $_, и все команды, которые принимают один аргумент, будут использовать это, если не указано (например: только вызов print; фактически переведёт на print $_;). Таким образом, в нашем коде оператор s/.../.../ работает один раз в каждой строке входного файла.

    • [^[:ascii:]] Второй аргумент - это шаблон для поиска во входной строке. Этот шаблон является регулярным выражением, поэтому все заключенное в пределах [] является скобкой. Этот раздел, вероятно, является самой сложной частью этого примера, поэтому мы подробно обсудим его в конце.

    • <empty string> Третий аргумент - это строка замены, которая в нашем случае является пустой строкой, так как мы хотим удалить все символы, отличные от 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 в командной строке, чтобы прочитать страницу руководства. Если нет, read the online version

[:ascii:] - класс символов, представляющий весь набор символов ascii, но этот тип символьного класса может использоваться только внутри выражения скобки. Правильный способ использования этого - [[:ascii:]], и он может быть отменен, как и в случае с abc, или комбинироваться в выражении скобки с другими символами, поэтому, например, [éç[:ascii:]] будет соответствовать всем символам ascii, а также é и ç, которые не являются ascii, и [^éç[:ascii:]] будут соответствовать всем символам, которые не являются ascii, а также не é или ç.

+0

просто сделал это перед тем, как увидеть ваш комментарий. – janar

+0

@bluesmoon Можете ли вы сломать это и объяснить, что происходит? –

+3

@JoshuaRobinson Я отредактировал ответ с подробным объяснением. – bluesmoon

8
tr -dc [:graph:][:cntrl:] < input-file > cleaned-file 

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

+3

'tr -dc '\ 11 \ 12 \ 15 \ 40- \ 176' cleaned- file' могут включать в себя многие вещи – user3338098

1

My two cents: Это может не решить вашу проблему, но это может дать вам несколько советов.

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

+1

iconv неожиданно лишил некоторые вещи тоже в XML-файле .. я сделал iconv -f ascii -t ascii -c – janar

5
perl -pe's/[[:^ascii:]]//g' <input.txt> output.txt 
+1

Это именно то, что я сделал, чтобы исправить эту проблему. – janar

3

Вы можете написать программу 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 
Смежные вопросы