(grep) Regex pour correspondre aux caractères non ASCII?


169

Sous Linux, j'ai un répertoire avec beaucoup de fichiers. Certains d'entre eux ont des caractères non ASCII, mais ils sont tous UTF-8 valides . Un programme a un bogue qui l'empêche de fonctionner avec des noms de fichiers non ASCII, et je dois savoir combien sont affectés. J'allais faire cela avec find, puis faire un grep pour imprimer les caractères non ASCII, puis faire un wc -lpour trouver le nombre. Il n'est pas nécessaire que ce soit grep; Je peux utiliser n'importe quelle expression régulière Unix standard , comme Perl , sed , AWK , etc.

Cependant, existe-t-il une expression régulière pour «tout caractère qui n'est pas un caractère ASCII»?


1
Paul, oui je peux utiliser perl
Rory

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

Réponses:


310

Cela correspondra à un seul caractère non ASCII:

[^\x00-\x7F]

Il s'agit d'un PCRE ( Expression régulière compatible Perl) valide .

Vous pouvez également utiliser les raccourcis POSIX :

  • [[:ascii:]] - correspond à un seul caractère ASCII
  • [^[:ascii:]] - correspond à un seul caractère non ASCII

[^[:print:]] vous suffira probablement. **


3
@adrianm: Non, ^est valide dans PCRE.
Alix Axel

10
C'est exactement ça. Cependant, vous devez utiliser pcregrep, pas grep standard. [^ [: print:]] ne fonctionnera pas si votre terminal est configuré en UTF8.
Rory

@Rory, pourquoi :print:ne fonctionnera pas dans un terminal UTF8? Cela fonctionne pour moi dans le levier dans un terminal UTF8:27.chr =~ /[^[:print:]]/
akostadinov

C'est vraiment bien pour corriger les mauvais noms de fichiers - rename 's/[^\x00-\x7F]//g' *(vous pouvez utiliser -npour vérifier que les renommages sont corrects en premier).
naught101

Comment faire correspondre un caractère non UTF8 et d'autres caractères spécifiques?
CMCDragonkai

37

Non, ce [^\x20-\x7E]n'est pas ASCII.

C'est du vrai ASCII:

 [^\x00-\x7F]

Sinon, il supprimera les nouvelles lignes et autres caractères spéciaux qui font partie de la table ASCII!



3

[^\x00-\x7F]et [^[:ascii:]]manquez quelques octets de contrôle afin que les chaînes soient parfois la meilleure option. Par exemple, cat test.torrent | perl -pe 's/[^[:ascii:]]+/\n/g'fera des choses bizarres sur votre terminal, où comme strings test.torrentse comportera.


3

Pour valider la zone de texte Accepter Ascii, utilisez uniquement ce modèle

[\x00-\x7F]+




2

Vous n'avez pas vraiment besoin d'une expression régulière.

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

Cela affichera également les noms de fichiers avec des caractères de contrôle dans leurs noms, mais je considère que c'est une fonctionnalité.

Si vous n'avez aucun fichier correspondant, le glob se développera uniquement sur lui-même, sauf si vous avez nullglobdéfini. (L'expression ne correspond pas à elle-même, donc techniquement, cette sortie est sans ambiguïté.)


Tardivement, je peux observer que cela ne fonctionnera correctement que si vous avez réellement des fichiers qui correspondent à ce modèle. Le comportement où le motif s'imprime lorsqu'il n'y a pas de correspondance est légèrement surprenant mais en fait correct. J'ai édité la réponse pour clarifier cela, espérons-le.
tripleee

1

Cela s'est avéré être très flexible et extensible. $ champ = ~ s / [^ \ x00- \ x7F] // g; # ainsi tous les éléments non ASCII ou spécifiques en question pourraient être nettoyés. Très agréable que ce soit dans la sélection ou le prétraitement des éléments qui finiront par devenir des clés de hachage.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.