(grep) Regex для соответствия не-ASCII символам?

169

В Linux у меня есть каталог с большим количеством файлов. Некоторые из них имеют символы не ASCII, но все они действительны в формате UTF-8 . В одной программе есть ошибка, которая не позволяет ей работать с именами, отличными от ASCII, и я должен выяснить, сколько из них затронуто. Я собирался сделать это с findи затем сделать grep, чтобы напечатать символы не ASCII, и затем сделать a, wc -lчтобы найти число. Это не должно быть grep; Я могу использовать любое стандартное регулярное выражение Unix , например Perl , sed , AWK и т. Д.

Однако существует ли регулярное выражение для «любого символа, который не является символом ASCII»?

Рори
источник
1
Пол, да, я могу использовать Perl
Рори
/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F-\x9F]
Тинмарино

Ответы:

310

Это будет соответствовать одному не-ASCII символу:

[^\x00-\x7F]

Это действительное PCRE ( Perl-совместимое регулярное выражение ).

Вы также можете использовать сокращения POSIX :

  • [[:ascii:]] - соответствует одному символу ASCII
  • [^[:ascii:]] - соответствует одному не-ASCII-символу

[^[:print:]] вероятно, будет достаточно для вас. **

Аликс Аксель
источник
3
@adrianm: Нет, ^действует в PCRE.
Аликс Аксель
10
Это точно верно. Однако вы должны использовать pcregrep, а не стандартный grep. [^ [: print:]] не будет работать, если ваш терминал настроен в UTF8.
Рори
@ Рори, почему :print:не работает в терминале UTF8? Это работает для меня в pry в терминале UTF8:27.chr =~ /[^[:print:]]/
akostadinov
Это очень удобно для исправления неправильных имен файлов rename 's/[^\x00-\x7F]//g' *(вы можете -nсначала проверить, что переименования в порядке).
naught101
Как мне сопоставить любой символ, отличный от UTF8, и любые другие конкретные символы?
CMCDragonkai
37

Нет, [^\x20-\x7E]это не ASCII.

Это настоящий ASCII:

 [^\x00-\x7F]

В противном случае он обрежет символы новой строки и другие специальные символы, которые являются частью таблицы ASCII!

Питер Л
источник
3

[^\x00-\x7F]и [^[:ascii:]]пропустить некоторые управляющие байты, так что иногда строки могут быть лучшим вариантом. Например cat test.torrent | perl -pe 's/[^[:ascii:]]+/\n/g'будет делать странные вещи с вашим терминалом, где так же strings test.torrentбудет себя вести.

user1133275
источник
3

Подтвердить текстовое поле Принять Ascii Используйте только этот шаблон

[\x00-\x7F]+

Осман Махмуд
источник
3

Я использую, [^\t\r\n\x20-\x7E]+и это, кажется, работает нормально.

SolidSnakeUk89
источник
2

Вы можете использовать это регулярное выражение:

[^\w \xC0-\xFF]

Дело спрашивают, варианты Multiline .

CypherPotato
источник
2

Вам не нужно регулярное выражение.

printf "%s\n" *[!\ -~]*

Это также покажет имена файлов с управляющими символами в их именах, но я считаю, что это особенность.

Если у вас нет подходящих файлов, глобус расширится до самого себя, если вы не nullglobустановили. (Выражение не соответствует самому себе, так что технически этот вывод однозначен.)

tripleee
источник
Запоздал, я могу заметить , что это делает работу правильно , если вы на самом деле есть некоторые файлы , которые соответствуют этому шаблону. Поведение, при котором шаблон печатается сам, когда нет совпадений, немного удивительно, но на самом деле правильно. Я отредактировал ответ, чтобы уточнить это.
tripleee
1

Это оказалось очень гибким и расширяемым. $ field = ~ s / [^ \ x00- \ x7F] // g; # Таким образом, все не ASCII или конкретные рассматриваемые элементы могут быть очищены. Очень хорош в выборе или предварительной обработке элементов, которые в конечном итоге станут хеш-ключами.

Дон Тернблейд
источник