Sous Windows, les extensions de fichiers sont généralement assez bon:
# all C# and related files (projects, source control metadata, etc)
dir -r -fil *.cs* | ss foo
# exclude the binary types most likely to pollute your development workspace
dir -r -exclude *exe, *dll, *pdb | ss foo
# stick the first three lines in your $profile (refining them over time)
$bins = new-list string
$bins.AddRange([string[]]@("exe", "dll", "pdb", "png", "mdf", "docx"))
function IsBin([System.IO.FileInfo]$item) { !$bins.Contains($item.extension.ToLower()) }
dir -r | ? { !IsBin($_) } | ss foo
Mais bien sûr, les extensions de fichiers ne sont pas parfaits. Personne n'aime taper de longues listes, et beaucoup de fichiers sont mal nommés de toute façon.
Je ne pense pas que Unix ait des indicateurs binaires ou textuels spéciaux dans le système de fichiers. (Eh bien, VMS l'a fait, mais je doute que ce soit la source de vos habitudes de grep.) J'ai regardé l'implémentation de Grep -I, et apparemment c'est juste une heuristique quick-n-dirty basée sur le premier morceau du fichier. Il s'avère que c'est une stratégie que j'ai avec a bit of experience. Voici donc mon conseil sur le choix d'une fonction heuristique appropriée pour les fichiers texte Windows:
- Examinez au moins 1 Ko du fichier. Beaucoup de formats de fichiers commencent par un en-tête ressemblant à du texte, mais qui va bientôt éclater votre analyseur. La façon dont le matériel moderne fonctionne, en lisant 50 octets a à peu près le même overhead d'E/S que la lecture de 4 Ko.
- Si vous ne vous souciez que de l'ASCII rectiligne, quittez dès que vous voyez quelque chose en dehors de la plage de caractères [31-127 plus CR et LF]. Vous pourriez accidentellement exclure un art ASCII intelligent, mais essayer de séparer ces cas d'ordure binaire est non trivial.
- Si vous souhaitez gérer le texte Unicode, laissez les bibliothèques MS gérer le travail sale. C'est plus difficile que tu ne le penses. De Powershell vous pouvez facilement accéder à la méthode statique IMultiLang2 interface (COM) ou Encoding.GetEncoding (.NET). Bien sûr, ils ne font que deviner.Les commentaires de Raymond sur le Notepad detection algorithm (et le lien vers Michael Kaplan) valent la peine d'être revus avant de décider exactement comment vous voulez mélanger & avec les bibliothèques fournies par la plateforme.
- Si le résultat est important - c'est à dire qu'une faille fera pire que de simplement encombrer votre console grep - alors n'ayez pas peur de coder en dur certaines extensions de fichiers par souci de précision. Par exemple, les fichiers * .PDF ont parfois plusieurs Ko de texte à l'avant, bien qu'ils soient en format binaire, ce qui conduit aux bogues notoires ci-dessus. De même, si vous avez une extension de fichier susceptible de contenir des données XML ou de type XML, vous pouvez essayer un schéma de détection similaire à Visual Studio's HTML editor. (SourceSafe 2005 emprunte cet algorithme pour certains cas)
- Quoi qu'il arrive, ayez un plan de sauvegarde raisonnable.
À titre d'exemple, voici le détecteur ASCII rapide:
function IsAscii([System.IO.FileInfo]$item)
{
begin
{
$validList = new-list byte
$validList.AddRange([byte[]] (10,13))
$validList.AddRange([byte[]] (31..127))
}
process
{
try
{
$reader = $item.Open([System.IO.FileMode]::Open)
$bytes = new-object byte[] 1024
$numRead = $reader.Read($bytes, 0, $bytes.Count)
for($i=0; $i -lt $numRead; ++$i)
{
if (!$validList.Contains($bytes[$i]))
{ return $false }
}
$true
}
finally
{
if ($reader)
{ $reader.Dispose() }
}
}
}
Le modèle d'utilisation je cible est une clause où-objet inséré dans le pipeline entre « dir » et « ss ». Il y a d'autres façons, en fonction de votre style de script.
L'amélioration de l'algorithme de détection le long d'un des chemins suggérés est laissée au lecteur.
edit: j'ai commencé à répondre à votre commentaire dans un commentaire de ma propre, mais il faisait trop longtemps ...
Au-dessus, je regarde le problème du POV de liste blanche en bon état des séquences. Dans l'application j'ai maintenu, en stockant incorrectement un binaire comme le texte avait des conséquences bien pires que vice versa. Il en va de même pour les scénarios dans lesquels vous choisissez le mode de transfert FTP à utiliser ou le type d'encodage MIME à envoyer à un serveur de messagerie, etc.
Dans d'autres scénarios, la mise en liste noire de l'évidence et de tout le reste Le texte appelé est une technique tout aussi valide. Alors que U + 0000 est un point de code valide, on ne le trouve pratiquement jamais dans un texte réel. Pendant ce temps, \ 00 est assez commun dans les fichiers binaires structurés (à savoir, chaque fois qu'un champ de longueur d'octet fixe a besoin d'un remplissage), donc il fait une grande liste noire simple. VSS 6.0 a utilisé cette vérification seule et a bien fait.
À côté: * Les fichiers .zip sont un cas où la vérification de \ 0 est plus risquée. Contrairement à la plupart des binaires, leur bloc structuré "header" (pied de page?) Est à la fin, pas le début. En supposant une compression entropique idéale, la probabilité de non \ 0 dans le premier 1KB est de (1-1/256)^1024 ou environ 2%. Heureusement, il suffit de scanner le reste du cluster NTFS de 4 Ko pour lire le risque jusqu'à 0,00001% sans devoir modifier l'algorithme ou écrire un autre cas particulier.
Pour exclure un fichier UTF-8 invalide, ajoutez \ C0-C1 et \ F8-FD et \ FE-FF (une fois que vous avez dépassé la nomenclature possible) dans la liste noire. Très incomplet puisque vous n'êtes pas en train de valider les séquences, mais assez proche pour vos objectifs. Si vous voulez obtenir un colombophile, il est temps d'appeler l'une des bibliothèques de la plate-forme comme IMultiLang2 :: DetectInputCodepage.
Vous ne savez pas pourquoi \ C8 (200 décimal) est sur la liste de Grep. Ce n'est pas un encodage trop long. Par exemple, la séquence \ C8 \ 80 représente Ȁ (U + 0200). Peut-être quelque chose de spécifique à Unix.
Pas un script PS, mais 'findstr' équivalent est' findstr/p' que j'utilise dans la console powershell comme ceci: 'doskey fs = findstr/spin/a: 4A $ *' puis utiliser comme fs ' –
orad