TL; DR:
grep -axv '.*' out.txt
longue réponse
Les deux réponses actuelles sont extrêmement trompeuses et fondamentalement erronées.
Pour tester, obtenez ces deux fichiers (d'un développeur très réputé: Markus Kuhn):
$ wget https://www.cl.cam.ac.uk/~mgk25/ucs/examples/UTF-8-demo.txt
$ wget https://www.cl.cam.ac.uk/~mgk25/ucs/examples/UTF-8-test.txt
Démo
Le premier UTF-8-demo.txt
est un fichier conçu pour montrer à quel point UTF-8 est capable de présenter de nombreuses langues, mathématiques, braille et de nombreux autres types de caractères utiles. Jetez un oeil avec un éditeur de texte (qui comprend utf-8) et vous verrez beaucoup d'exemples et non �
.
Le test que propose une réponse: limiter la plage de caractères à \x00-\x7F
rejettera presque tout ce qui se trouve dans ce fichier.
C'est très faux et n'en supprimera aucun �
car il n'y en a pas dans ce fichier .
L'utilisation du test recommandé dans cette réponse supprimera 72.5 %
le fichier:
$ grep -oP "[^\x00-\x7F]" UTF-8-demo.txt | tr -d '\n' | wc -c
10192
$ cat UTF-8-demo.txt | wc -c
14058
Il s'agit (à des fins plus pratiques) de l'ensemble du dossier. Un fichier très bien conçu pour montrer des caractères parfaitement valides.
Tester
Le deuxième fichier est conçu pour essayer plusieurs cas de frontière afin de confirmer que les lecteurs utf-8 font du bon travail. Il contient à l'intérieur de nombreux caractères qui feront apparaître un ' '. Mais l'autre recommandation de réponse (celle sélectionnée) à utiliser file
échoue grossièrement avec ce fichier. Seule la suppression d'un octet zéro ( \0
) (qui est techniquement valide ASCII) et d'un \x7f
octet (DEL - supprimer) (qui est clairement un caractère ASCII également) rendra tout le fichier valide pour la file
commande:
$ cat UTF-8-test.txt | tr -d '\0\177' > a.txt
$ file a.txt
a.txt: Non-ISO extended-ASCII text, with LF, NEL line terminators
Non seulement ne parvient file
pas à détecter les nombreux caractères incorrects, mais également à détecter et à signaler qu'il s'agit d'un fichier codé UTF-8.
Et oui, file
est capable de détecter et de signaler du texte encodé en UTF-8:
$ echo "ééakjfhhjhfakjfhfhaéá" | file -
/dev/stdin: UTF-8 Unicode text
Également, file
ne signale pas en ASCII la plupart des caractères de contrôle compris entre 1 et 31. Il ( file
) signale certaines plages comme data
:
$ printf '%b' "$(printf '\\U%x' {1..6})" | file -
/dev/stdin: data
D'autres comme ASCII text
:
$ printf '%b' "$(printf '\\U%x' 7 {9..12})" | file -
/dev/stdin: ASCII text
En tant que plage de caractères imprimables (avec sauts de ligne):
$ printf '%b' "$(printf '\\U%x' {32..126} 10)" | file -
/dev/stdin: ASCII text
Mais certaines plages peuvent provoquer des résultats étranges:
$ printf '%b' "$(printf '\\U%x' {14..26})" | file -
/dev/stdin: Atari MSA archive data, 4113 sectors per track, starting track: 5141, ending track: 5655
Le programme file
n'est pas un outil pour détecter du texte, mais pour détecter des nombres magiques dans des programmes ou fichiers exécutables.
Les plages file
détectent et le type correspondant signalé que j'ai trouvé était:
Valeurs d'un octet, principalement ascii:
{1..6} {14..26} {28..31} 127 :data
{128..132} {134..159} :Non-ISO extended-ASCII text
133 :ASCII text, with LF, NEL line terminators
27 :ASCII text, with escape sequences
13 :ASCII text, with CR, LF line terminators
8 :ASCII text, with overstriking
7 {9..12} {32..126} :ASCII text
{160..255} :ISO-8859 text
Plages codées Utf-8:
{1..6} {14..26} {28..31} 127 :data
27 :ASCII text, with escape sequences
13 :ASCII text, with CR, LF line terminators
8 :ASCII text, with overstriking
7 {9..12} {32..126} :ASCII text
{128..132} {134..159} :UTF-8 Unicode text
133 :UTF-8 Unicode text, with LF, NEL line terminators
{160..255} :UTF-8 Unicode text
{256..5120} :UTF-8 Unicode text
Une solution possible se trouve ci-dessous.
Réponse précédente.
La valeur Unicode du personnage que vous publiez est:
$ printf '%x\n' "'�"
fffd
Oui, c'est un caractère Unicode 'CHARGEUR DE REMPLACEMENT' (U + FFFD) . Il s'agit d'un caractère utilisé pour remplacer tout caractère Unicode non valide trouvé dans le texte. C'est une "aide visuelle", pas un vrai personnage. Pour rechercher et répertorier chaque ligne complète contenant des caractères UNICODE non valides, utilisez:
grep -axv '.*' out.txt
mais si vous voulez seulement détecter si un caractère n'est pas valide, utilisez:
grep -qaxv '.*' out.txt; echo $?
Si le résultat est que 1
le fichier est propre, sinon il sera nul 0
.
Si ce que vous demandiez était: comment trouver le �
personnage, alors utilisez ceci:
➤ a='Basically, if the file "out.txt" contains "�" anywhere in the file I'
➤ echo "$a" | grep -oP $(printf %b \\Ufffd)
�
Ou si votre système traite correctement le texte UTF-8, simplement:
➤ echo "$a" | grep -oP '�'
�
grep
comprend depuis longtemps unicode (ce qui le rend beaucoup plus lent, donc pour rechercher des chaînes ascii, aLANG=C grep
est une énorme amélioration des performances).