J'ai une image de disque de 30 Go d'une partition bouchée (pense dd if=/dev/sda1 of=diskimage
) que j'ai besoin de récupérer certains fichiers texte de. Les outils de sculpture de données tels que foremost
ne fonctionnent que sur des fichiers avec des en-têtes bien définis, c'est-à-dire des fichiers texte simples, donc je suis tombé sur mon bon ami strings
.
strings diskimage > diskstrings.txt
Produit un fichier texte de 3 Go contenant une bouquet de chaînes, principalement des objets inutiles, mélangés au texte que je veux réellement.
La majeure partie de la cruft a tendance à être vraiment longues, des cordes ininterrompues de gibberish. Le contenu que je suis intéressé est garanti d'être inférieur à 16 Ko, alors je vais filtrer le fichier par longueur de ligne. Voici le Python script que j'utilise pour le faire:
infile = open ("infile.txt" ,"r");
outfile = open ("outfile.txt","w");
for line in infile:
if len(line) < 16384:
outfile.write(line)
infile.close()
outfile.close()
Cela fonctionne, mais pour une référence future: y a-t-il des incantations magiques d'une ligne (pensez awk
, sed
) qui filtrerait un fichier par ligne de ligne?
awk '{ if (length($0) < 16384) print }' yourfile >your_output_file.txt
imprimerait des lignes plus courtes que 16 kilo-octets, comme dans votre propre exemple.
Ou si vous avez envie de Perl:
Perl -nle 'if (length($_) < 16384) { print }' yourfile >your_output_file.txt
Ceci est similaire à la réponse d'Ansgar, mais légèrement plus rapide dans mes tests:
awk 'length($0) < 16384' infile >outfile
C'est la même vitesse que les autres réponses AWK. Il repose sur l'implicite print
d'une véritable expression, mais n'a pas besoin de prendre le temps de diviser la ligne d'ANSGAR.
Notez que AWK vous donne un if
gratuitement. La commande ci-dessus est équivalente à:
awk 'length($0) < 16384 {print}' infile >outfile
Il n'y a pas de if
(ou son ensemble d'accolades bouclés) comme dans certaines des autres réponses.
Voici un moyen de le faire dans sed
:
sed '/.\{16384\}/d' infile >outfile
ou:
sed -r '/.{16384}/d' infile >outfile
qui suppriment une ligne contenant 16384 caractères (ou plus).
Pour complétude, voici comment vous utiliseriez sed
pour enregistrer des lignes plus longtemps que votre seuil:
sed '/^.\{0,16383\}$/d' infile >outfile
Pas vraiment différent des réponses déjà données, mais plus courte encore:
awk -F '' 'NF < 16384' infile >outfile
Vous pouvez awk
tel que:
$ awk '{ if (length($0) < 16384) { print } }' /path/to/text/file
Cela imprimera les lignes plus courtes que 16k caractères (16 * 1024).
Vous pouvez utiliser grep
aussi:
$ grep ".\{,16384\}" /path/to/text/file
Cela imprimera les lignes au plus de caractères 16k.