2010-01-23 11 views
127

Sur Linux, j'ai un répertoire avec beaucoup de fichiers. Certains d'entre eux ont des caractères non-ASCII, mais ils sont tous valides UTF-8. Un programme a un bug qui l'empêche de travailler avec des noms de fichiers non-ASCII, et je dois savoir combien sont affectés. J'allais le faire avec find et ensuite faire un grep pour imprimer les caractères non-ASCII, puis faire un wc -l pour trouver le numéro. Il ne doit pas forcément être grep; Je peux utiliser un standard Unix regular expression, comme Perl, sed, AWK, etc.(grep) Regex pour faire correspondre les caractères non-ASCII?

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

+2

est-ce que perl est installé? –

+1

Paul, oui je peux utiliser perl – Rory

Répondre

221

Cela correspondra à un seul caractère non-ASCII:

[^\x00-\x7F] 

Ceci est valide PCRE (Perl-Compatible Regular Expression).

Vous pouvez également utiliser les POSIX sténographies:

  • [[:ascii:]] - correspond à un seul char ASCII
  • [^[:ascii:]] - correspond à un seul ombles non ASCII

[^[:print:]] sera probablement suffisant pour vous. **

+0

ne veux pas dire [~ \ x20- \ x7f] – adrianm

+2

@adrianm: Non, '^' est valide dans PCRE. –

+10

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

4

Vous pouvez également consulter cette page: Unicode Regular Expressions, car il contient certaines classes de caractères Unicode utiles, comme:

\p{Control}: an ASCII 0x00..0x1F or Latin-1 0x80..0x9F control character.
+0

[le grep standard ne les supporte pas] (https://www.gnu.org/software/grep/manual/grep.html). – eis

1

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

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

Cela montrera les noms de fichiers contenant des caractères de contrôle dans leurs noms aussi, mais je considère qu'une caractéristique.

Si vous n'avez aucun fichier correspondant, le glob sera étendu à rien.

+1

Bizarrement, cela ne fonctionne pas correctement dans Bash. – tripleee

26

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

Ceci est vrai ASCII:

[^\x00-\x7F] 

Sinon, il taillera des sauts de ligne et autres caractères spéciaux qui font partie de la table ASCII!

0

Vous pouvez utiliser cette regex:

[^\w \xC0-\xFF] 

cas Interrogez, les options est multiligne.

0

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

1

[^\x00-\x7F] et [^[:ascii:]] manquer certains octets de contrôle ainsi strings peut être la meilleure option parfois. Par exemple cat test.torrent | perl -pe 's/[^[:ascii:]]+/\n/g' fera des choses étranges à votre terminal, où strings test.torrent se comportera.

Questions connexes