Comment vérifier si le fichier est un fichier binaire et lire tous les fichiers qui ne le sont pas?
Comment savoir si un fichier est un fichier binaire?
par exemple, fichier c compilé.
je veux lire tous les fichiers d'un répertoire, mais je veux ignorer les fichiers binaires.
12 réponses
  Utilisation de l'utilitaire  file  , exemple d'utilisation:  
 $ file /bin/bash
 /bin/bash: Mach-O universal binary with 2 architectures
 /bin/bash (for architecture x86_64):   Mach-O 64-bit executable x86_64
 /bin/bash (for architecture i386): Mach-O executable i386
 $ file /etc/passwd
 /etc/passwd: ASCII English text
 $ file code.c
 code.c: ASCII c program text
adapté de à l'exclusion du fichier binaire
find . -exec file {} \; | grep text | cut -d: -f1
j'utilise
! grep -qI . $path
Seul inconvénient que je vois c'est qu'il envisagera d'un fichier vide binaire mais là encore, qui décide si c'est faux?
perl -E 'exit((-B $ARGV[0])?0:1);' file-to-test
peut être utilisé pour vérifier chaque fois que" file-to-test " est binaire. La commande ci-dessus va sortir le code wit 0 sur les fichiers binaires, sinon le code de sortie serait 1.
la vérification inverse du fichier texte peut ressembler à la commande suivante:
perl -E 'exit((-T $ARGV[0])?0:1);' file-to-test
de même, la commande ci-dessus quittera avec l'état 0 si le" fichier à tester " est du texte (Pas binaire).
  plus d'informations à propos des contrôles  -B  et  -T   en utilisant la commande  perldoc -f -X .  
    BSD  grep      
  
    Voici une solution simple pour vérifier un fichier unique en utilisant    BSD  grep     (sur macOS/Unix):  
grep -q "\x00" file && echo Binary || echo Text
qui vérifie si le fichier est composé D'un caractère NUL.
  en utilisant cette méthode, pour lire tous les fichiers non binaires récursivement en utilisant  find  utilitaire, vous pouvez faire:  
find . -type f -exec sh -c 'grep -q "\x00" {} || cat {}' ";"
  ou encore plus simple en utilisant juste  grep :  
grep -rv "\x00" .
pour juste le dossier courant, utilisez:
grep -v "\x00" *
 malheureusement les exemples ci-dessus ne fonctionneront pas pour  GNU grep   , cependant il y a une solution.  
     GNU  grep      
  
    puisque GNU grep  ignore les caractères nuls, il est possible de    vérifier pour les autres caractères non ASCII    comme:  
$ grep -P "[^\x00-\x7F]" file && echo Binary || echo Text
Note: cela ne fonctionnera pas pour les fichiers contenant seulement des caractères nuls.
 utilisez L'opérateur de test de fichier -T  intégré à Perl, de préférence après s'être assuré qu'il s'agit d'un fichier simple en utilisant l'opérateur de test de fichier  -f :  
$ perl -le 'for (@ARGV) { print if -f && -T }' \
    getwinsz.c a.out /etc/termcap /bin /bin/cat \
    /dev/tty /usr/share/zoneinfo/UTC /etc/motd
getwinsz.c
/etc/termcap
/etc/motd
voici le complément de cet ensemble:
$ perl -le 'for (@ARGV) { print unless -f && -T }' \
    getwinsz.c a.out /etc/termcap /bin /bin/cat \
    /dev/tty /usr/share/zoneinfo/UTC /etc/motd
a.out
/bin
/bin/cat
/dev/tty
/usr/share/zoneinfo/UTC
essayez la ligne de commande suivante:
file "$FILE" | grep -vq 'ASCII' && echo "$FILE is binary"
   cat  +  grep   
  
  en supposant que binaire signifie le fichier contenant des caractères nuls, cette commande shell peut aider:
(cat -v file.bin | grep -q "\^@") && echo Binary || echo Text
ou:
grep -q "\^@" <(cat -v file.bin) && echo Binary
  c'est la solution pour     grep -q "\x00"     , qui fonctionne pour BSD grep, mais pas pour la version GNU.  
  essentiellement  -v  pour cat  convertit tous les caractères non imprimants de sorte qu'ils sont visible sous forme de caractères de contrôle, par exemple:  
$ printf "\x00\x00" | hexdump -C
00000000  00 00                                             |..|
$ printf "\x00\x00" | cat -v
^@^@
$ printf "\x00\x00" | cat -v | hexdump -C
00000000  5e 40 5e 40                                       |^@^@|
  où les caractères  ^@  représentent le caractère nul. Donc, une fois que ces caractères de contrôle sont trouvés, nous supposons que le fichier est binaire.  
l'inconvénient de la méthode ci-dessus est qu'elle peut générer des faux positifs lorsque les caractères ne représentent pas les caractères de contrôle. Par exemple:
$ printf "\x00\x00^@^@" | cat -v | hexdump -C
00000000  5e 40 5e 40 5e 40 5e 40                           |^@^@^@^@|
voir aussi: Comment puis-je noter tous les caractères non-ASCII .
  Going off    suggestion de Bach   , je pense que  --mime-encoding  est le meilleur drapeau pour obtenir quelque chose de fiable de     file     .  
file --mime-encoding [FILES ...] | grep -v '\bbinary$'
 affichera les fichiers dont file  pense qu'ils ont un encodage non binaire. Vous pouvez utiliser  cut -d: -f1 pour couper le :   encoding  si vous voulez simplement les noms de fichiers.  
  mise en garde: as @yugr rapporte ci-dessous  Les fichiers  .doc rapportent un encodage de application/mswordbinary . Cela me semble être un bug - le type mime est concaténé par erreur avec l'encodage.  
$ for flag in --mime --mime-type --mime-encoding; do
    echo "$flag"
    file "$flag" /tmp/example.{doc{,x},png,txt}
  done
--mime
/tmp/example.doc:  application/msword; charset=binary
/tmp/example.docx: application/vnd.openxmlformats-officedocument.wordprocessingml.document; charset=binary
/tmp/example.png:  image/png; charset=binary
/tmp/example.txt:  text/plain; charset=us-ascii
--mime-type
/tmp/example.doc:  application/msword
/tmp/example.docx: application/vnd.openxmlformats-officedocument.wordprocessingml.document
/tmp/example.png:  image/png
/tmp/example.txt:  text/plain
--mime-encoding
/tmp/example.doc:  application/mswordbinary
/tmp/example.docx: binary
/tmp/example.png:  binary
/tmp/example.txt:  us-ascii
 c'est une sorte de force brute pour exclure les fichiers binaires avec tr -d "[[:print:]\n\t]" < file | wc -c , mais ce n'est pas non plus une supposition heuristique.  
find . -type f -maxdepth 1 -exec /bin/sh -c '
   for file in "$@"; do
      if [ $(LC_ALL=C LANG=C tr -d "[[:print:]\n\t]" < "$file" | wc -c) -gt 0 ]; then
         echo "${file} is no ASCII text file (UNIX)"
      else
         echo "${file} is ASCII text file (UNIX)"
      fi
   done
' _ '{}' +
 l'approche de force brute suivante utilisant grep -a -m 1 $'[^[:print:]\t]' file  semble un peu plus rapide, cependant.  
find . -type f -maxdepth 1 -exec /bin/sh -c '
   tab="$(printf "\t")"
   for file in "$@"; do
      if LC_ALL=C LANG=C grep -a -m 1 "[^[:print:]${tab}]" "$file" 1>/dev/null 2>&1; then
         echo "${file} is no ASCII text file (UNIX)"
      else
         echo "${file} is ASCII text file (UNIX)"
      fi
   done
' _ '{}' + 
 vous pouvez faire cela aussi en utilisant la commande diff . Cochez cette réponse:  
  grep   
  
  en supposant que le fichier binaire signifie un fichier contenant des caractères non imprimables (à l'exclusion des caractères Vierges tels que les espaces, les onglets ou les caractères de nouvelle ligne), cela peut fonctionner (à la fois BSD et GNU):
$ grep '[^[:print:][:blank:]]' file && echo Binary || echo Text
     Note:    GNU  grep     rapportera fichier contenant seulement des caractères nuls comme texte, mais il fonctionnerait correctement sur    version BSD   .     
Pour plus d'exemples, voir: Comment puis-je grep pour tous les caractères non-ASCII .