(grep) Regex agar sesuai dengan karakter non-ASCII?

169

Di Linux, saya memiliki direktori dengan banyak file. Beberapa dari mereka memiliki karakter non-ASCII, tetapi semuanya adalah UTF-8 yang valid . Satu program memiliki bug yang mencegahnya bekerja dengan nama file non-ASCII, dan saya harus mencari tahu berapa banyak yang terpengaruh. Saya akan melakukan ini dengan finddan kemudian melakukan grep untuk mencetak karakter non-ASCII, dan kemudian melakukan a wc -luntuk menemukan nomornya. Tidak harus grep; Saya dapat menggunakan ekspresi reguler standar Unix , seperti Perl , sed , AWK , dll.

Namun, apakah ada ekspresi reguler untuk 'karakter apa pun yang bukan karakter ASCII'?

Rory
sumber
1
Paul, ya saya bisa menggunakan perl
Rory
/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F-\x9F]
Tinmarino

Jawaban:

310

Ini akan cocok dengan satu karakter non-ASCII:

[^\x00-\x7F]

Ini adalah PCRE ( Ekspresi Reguler Perl Kompatibel Kompatibel ) yang valid .

Anda juga dapat menggunakan singkatan POSIX :

  • [[:ascii:]] - Cocok dengan satu karakter ASCII
  • [^[:ascii:]] - Cocok dengan satu karakter non-ASCII

[^[:print:]] mungkin akan cukup untuk Anda. **

Alix Axel
sumber
3
@adrianm: Tidak, ^valid di PCRE.
Alix Axel
10
Benar sekali. Namun Anda harus menggunakan pcregrep, bukan grep standar. [^ [: print:]] tidak akan berfungsi jika terminal Anda diatur di UTF8.
Rory
@Rory, mengapa :print:tidak bekerja di terminal UTF8? Ini bekerja untuk saya di pry di terminal UTF8:27.chr =~ /[^[:print:]]/
akostadinov
Ini sangat bagus untuk memperbaiki nama file yang buruk - rename 's/[^\x00-\x7F]//g' *(Anda dapat menggunakannya -nuntuk memeriksa nama-nama yang ok terlebih dahulu).
naught101
Bagaimana cara mencocokkan karakter yang bukan UTF8 dan karakter spesifik lainnya?
CMCDragonkai
37

Tidak, [^\x20-\x7E]bukan ASCII.

Ini ASCII yang asli:

 [^\x00-\x7F]

Jika tidak, ini akan memangkas baris baru dan karakter khusus lainnya yang merupakan bagian dari tabel ASCII!

Peter L.
sumber
3

[^\x00-\x7F]dan [^[:ascii:]]kehilangan beberapa byte kontrol sehingga string bisa menjadi pilihan yang lebih baik kadang-kadang. Misalnya cat test.torrent | perl -pe 's/[^[:ascii:]]+/\n/g'akan melakukan hal-hal aneh ke terminal Anda, di mana seperti strings test.torrentakan berperilaku.

pengguna1133275
sumber
3

Memvalidasi Kotak Teks Terima Ascii Hanya gunakan Pola ini

[\x00-\x7F]+

Othman Mahmoud
sumber
3

Saya menggunakan [^\t\r\n\x20-\x7E]+dan itu tampaknya berfungsi dengan baik.

SolidSnakeUk89
sumber
2

Anda dapat menggunakan regex ini:

[^\w \xC0-\xFF]

Case ask, opsinya adalah Multiline .

CypherPotato
sumber
2

Anda tidak benar-benar membutuhkan regex.

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

Ini akan menunjukkan nama file dengan karakter kontrol di namanya juga, tetapi saya menganggap itu sebagai fitur.

Jika Anda tidak memiliki file yang cocok, glob akan berkembang menjadi sendiri, kecuali jika Anda telah nullglobmenetapkan. (Ekspresi tidak cocok dengan dirinya sendiri, jadi secara teknis, output ini tidak ambigu.)

tripleee
sumber
Terlambat, saya dapat mengamati bahwa ini tidak bekerja dengan benar jika Anda benar-benar memiliki beberapa file yang cocok dengan pola ini. Perilaku di mana pola mencetak sendiri ketika tidak ada kecocokan sedikit mengejutkan tetapi sebenarnya benar. Saya mengedit jawaban untuk mudah-mudahan memperjelas ini.
tripleee
1

Ini ternyata sangat fleksibel dan dapat diperpanjang. $ field = ~ s / [^ \ x00- \ x7F] // g; # dengan demikian semua non ASCII atau item tertentu yang dimaksud dapat dibersihkan. Sangat bagus baik dalam pemilihan atau pra-pemrosesan item yang pada akhirnya akan menjadi kunci hash.

Don Turnblade
sumber