(grep) Regex per abbinare caratteri non ASCII?


169

Su Linux, ho una directory con molti file. Alcuni di essi hanno caratteri non ASCII, ma sono tutti UTF-8 validi . Un programma ha un bug che gli impedisce di lavorare con nomi di file non ASCII e devo scoprire quanti ne sono interessati. Stavo per fare questo con finde poi fare un grep per stampare i caratteri non ASCII, quindi fare un wc -lper trovare il numero. Non deve essere grep; Posso usare qualsiasi espressione regolare standard Unix , come Perl , sed , AWK , ecc.

Tuttavia, esiste un'espressione regolare per "qualsiasi carattere che non sia un carattere ASCII"?


1
Paul, sì, posso usare perl
Rory il

/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F-\x9F]
Tinmarino,

Risposte:


310

Questo corrisponderà a un singolo carattere non ASCII:

[^\x00-\x7F]

Questo è un PCRE valido ( espressione regolare compatibile Perl ).

Puoi anche usare le shorthands POSIX :

  • [[:ascii:]] - corrisponde a un singolo carattere ASCII
  • [^[:ascii:]] - corrisponde a un singolo carattere non ASCII

[^[:print:]] sarà probabilmente sufficiente per te. **


3
@adrianm: No, ^è valido in PCRE.
Alix Axel,

10
Esatto. Comunque devi usare pcregrep, non grep standard. [^ [: print:]] non funzionerà se il tuo terminale è impostato in UTF8.
Rory,

@Rory, perché :print:non funziona in un terminale UTF8? Questo funziona per me in prigione in un terminale UTF8:27.chr =~ /[^[:print:]]/
Akostadinov

Questo è davvero utile per correggere i nomi di file errati rename 's/[^\x00-\x7F]//g' *(è possibile utilizzare -nper verificare prima che i nomi siano ok).
nulla101

Come posso abbinare qualsiasi personaggio che non sia UTF8 e altri caratteri specifici?
CMCDragonkai,

37

No, [^\x20-\x7E]non è ASCII.

Questo è vero ASCII:

 [^\x00-\x7F]

Altrimenti, taglierà nuove linee e altri caratteri speciali che fanno parte della tabella ASCII!



3

[^\x00-\x7F]e [^[:ascii:]]manca alcuni byte di controllo in modo che a volte le stringhe possano essere l'opzione migliore. Ad esempio cat test.torrent | perl -pe 's/[^[:ascii:]]+/\n/g'farà cose strane sul tuo terminale, dove strings test.torrentsi comporterà.


3

Per convalidare la casella di testo Accetta Ascii Utilizzare solo questo modello

[\x00-\x7F]+



2

Puoi usare questo regex:

[^\w \xC0-\xFF]

Caso chiedere, le opzioni sono Multiline .


2

Non hai davvero bisogno di una regex.

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

Questo mostrerà anche i nomi dei file con caratteri di controllo nei loro nomi, ma ritengo che sia una caratteristica.

Se non si dispone di file corrispondenti, il glob si espanderà su se stesso, a meno che non sia stato nullglobimpostato. (L'espressione non corrisponde a se stessa, quindi tecnicamente questo output non è ambiguo.)


In ritardo, posso osservare che questo fa il lavoro in modo corretto se effettivamente dispone di alcuni file che corrispondono a questo schema. Il comportamento in cui il motivo si stampa da solo quando non ci sono corrispondenze è leggermente sorprendente ma in realtà corretto. Ho modificato la risposta per chiarire, si spera.
triplo il

1

Ciò si è rivelato molto flessibile ed estensibile. $ field = ~ s / [^ \ x00- \ x7F] // g; # quindi tutti gli oggetti non ASCII o specifici in questione potrebbero essere puliti. Molto bello sia nella selezione che nella pre-elaborazione di elementi che alla fine diventeranno chiavi hash.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.