Quelle est la commande de ligne de commande Linux qui peut identifier de tels fichiers?
AFAIK la find
commande (ou grep
) ne peut correspondre qu'à une chaîne spécifique à l'intérieur du fichier texte. Mais je veux faire correspondre le contenu entier, c'est-à-dire que je veux voir quels fichiers correspondent à l'expression régulière \0+
, en ignorant les caractères de fin de ligne . Peut-être que l' find . cat | grep
idiome pourrait fonctionner, mais je ne sais pas comment faire grep en ignorant les lignes (et traiter le fichier comme binaire).
Contexte: Tous les quelques jours, lorsque mon ordinateur portable se bloque, ma partition btrfs perd des informations: les fichiers ouverts en écriture voient leur contenu remplacé par des zéros (la taille du fichier reste plus ou moins intacte). J'utilise la synchronisation et je ne veux pas que ces faux fichiers se propagent: j'ai besoin d'un moyen de les identifier afin de pouvoir les récupérer depuis la sauvegarde.
la source
-v
option de grep: filtrer tous les fichiers qui ont des octets de 1 à 255.Réponses:
Vous pouvez
grep
pour ␀ caractères en utilisant le mode regex Perl:Vous pouvez donc utiliser ceci:
la source
GNU grep 2.5.4
. Peu importe si j'utilise--binary-files=text
ou--binary-files=binary
, cela donne untrue
résultat pour toutes les valeurs de données non vides, par exemple."\0\0"
,"\0x\0"
,"abcd"
... Le code exact j'ai utilisé est:for typ in binary text ;do for dat in '\0\0' '\0x\0' 'abcd' '' ;do printf "$dat" >f; grep --binary-files=$typ -P '[^\0]' f >/dev/null && echo true || echo false; done; done
GNU grep) 2.10
. Cette version ultérieure donne les résultats escomptés ... alors, un +1 tardifprintf '\0\n\0\0\n\n' > file
ouprintf '\n' > file
pour ce qui compte.\0
et de\n
caractères (même zéro de l'un ou l'autre) serait une correspondance.Je suis d'accord avec ce que D_Bye dit sur la recherche de la racine du problème.
Quoi qu'il en soit pour vérifier si un fichier contient uniquement
\0
et / ou\n
vous pouvez utilisertr
:Qui renvoie 0 pour les fichiers null / newline et vides.
la source
tr -d '\0\n'
résout le problème de nouvelle ligne, qui ne laisse alors que le problème (?) des fichiers vides répertoriés dans la sortie ... Il traite cependant chaque octet de chaque fichier (qui peut ou non être un problème) +1Je soupçonne que ces fichiers sont rares, c'est-à-dire qu'ils n'ont pas d'espace disque alloué, ils spécifient simplement une taille de fichier (
du
rapporterait 0 pour eux).Dans ce cas, avec GNU find, vous pouvez faire (en supposant qu'aucun chemin de fichier ne contient de caractères de nouvelle ligne):
la source
du
empêchera de rayer le contenu de chaque fichier du système de fichiers, de sorte que toute la procédure ne prendrait pas plus de 30 minutes.printf %b
ci - dessus rapporte cedu
qui rapporterait)-size +0
pour-size +1
que les fichiers de longueur nulle soient exclus des résultats. De plus, les fichiers contenant\n
dans leur chemin entraîneront des problèmes pour cette commande.-size +0
est pour des tailles strictement supérieures à 0.-size +1
serait pour des tailles strictement supérieures à 512. La limitation de la nouvelle ligne a déjà été mentionnée.-size +1
, vous avez en effet raison. J'ai corrigé ma réponse. :-)Voici un petit programme python qui peut le faire:
Et en action:
Vous pouvez vérifier plusieurs fichiers en utilisant FIND
-exec
,xargs
, GNUparallel
, et des programmes similaires. Alternativement, cela imprimera les noms de fichiers qui doivent être traités:Gardez à l'esprit que si vous allez transmettre la sortie de ceci à un autre programme, les noms de fichiers peuvent contenir des sauts de ligne, vous devez donc les délimiter différemment (convenablement, avec
\0
).Si vous avez beaucoup de fichiers, il serait préférable d'utiliser une option pour le traitement parallèle, car elle ne lit qu'un fichier à la fois.
la source
/etc/nologin
,~/.hushlogin
,.nomedia
, ...) sont mal identifiés par cette réponse.Recherchez les fichiers qui contiennent uniquement des caractères nuls '\ 0' et des caractères de nouvelle ligne '\ n'.
Le
q
dans sed fait que chaque fichier recherche de quitter immédiatement à trouver un caractère non nul en ligne.Créer des fichiers de test
production
la source
-print0
argument semble manquer,find
soit laIFS=
pièce est foirée. Quel était le délimiteur prévu?Cette ligne unique est le moyen le plus efficace de trouver 100% des fichiers NUL en utilisant GNU
find
,xargs
etgrep
( en supposant que ce dernier est construit avec le soutien PCRE):Les avantages de cette méthode par rapport aux autres réponses fournies sont:
Permission denied
avertissements.grep
arrêtera la lecture des données des fichiers après avoir trouvé un octet non nul (LC_ALL=C
est utilisé pour s'assurer que chaque octet est interprété comme un caractère ).grep
processus vérifient efficacement plusieurs fichiers.-
sont traités correctement.Passer l'
-Z
optiongrep
et l'utiliserxargs -r0 ...
permet d'effectuer d'autres actions sur les fichiers 100% nul (ex: nettoyage):Je recommande également d'utiliser les
find
options-P
pour éviter de suivre les liens symboliques et-xdev
pour éviter de traverser les systèmes de fichiers (par exemple: montages distants, arborescences de périphériques, montages de liaison, etc.).Pour ignorer les caractères de fin de ligne , la variante suivante devrait fonctionner (bien que je ne pense pas que ce soit une si bonne idée):
Tout rassembler, y compris la suppression des fichiers indésirables (caractères 100% nul / newline) pour les empêcher d'être sauvegardés:
Je ne recommande pas d'inclure des fichiers vides (zéro octet), ils existent souvent à des fins très spécifiques .
la source
\0
avec 900 Mo de trou dedans) et moment actuel des résultats. Si vous le faites d'une manière que l'indice de référence vous convainque, il conviendra probablement à nous tous-P
est la valeur par défaut dansfind
. Si vous voulez suivre les liens symboliques, c'est-L
/-follow
. Vous constaterez que POSIX ne spécifie même pas cette option pourfind
(même si POSIX est celui qui a introduit ces -P / -H / -L pour quelques commandes).Pour utiliser GNU sed, vous pouvez utiliser l'
-z
option, qui définit une ligne comme des chaînes terminées par zéro et correspond et supprime les lignes vides comme suit:La commande head entre les deux n'est qu'une optimisation.
la source
Python
Un seul fichier
Définissez l'alias:
Essaye-le:
Fichiers multiples
Recherchez tous les fichiers binaires de manière récursive:
Pour rechercher tous les fichiers non binaires, modifiez
&&
avec||
.la source