Je suppose que tout le monde connaît les utilitaires utiles de la ligne cmd de Linux head
et tail
. head
vous permet d'imprimer les X premières lignes d'un fichier, tail
fait de même mais imprime la fin du fichier. Qu'est-ce qu'une bonne commande pour imprimer le milieu d'un fichier? quelque chose comme middle --start 10000000 --count 20
(imprimez les 10 000 000 000 à 10 000 000 €).
Je cherche quelque chose qui traitera efficacement les gros fichiers. J'ai essayé tail -n 10000000 | head 10
et c'est horriblement lent.
sed -n '10000000,10000020p' filename
Vous pourriez peut-être accélérer un peu comme ceci:
sed -n '10000000,10000020p; 10000021q' filename
Dans ces commandes, l'option -n
oblige sed
à "supprimer l'impression automatique de l'espace de motif". La commande p
"imprime [s] l'espace de motif courant" et la commande q
"Quitte immédiatement [s] le script sed sans traiter plus d'entrée ..." Les guillemets proviennent de la sed
man
page .
Au fait, votre commande
tail -n 10000000 filename | head 10
commence à la dix millionième ligne de la fin du fichier, tandis que votre commande "milieu" semble commencer à la dix millionième de la début qui serait équivalent à:
head -n 10000010 filename | tail 10
Le problème est que pour les fichiers non triés avec des lignes de longueur variable, tout processus devra passer par les nouvelles lignes de comptage de fichiers. Il n'y a aucun moyen de raccourcir cela.
Si, cependant, le fichier est trié (un fichier journal avec des horodatages, par exemple) ou a des lignes de longueur fixe, vous pouvez rechercher dans le fichier en fonction d'une position d'octet. Dans l'exemple de fichier journal, vous pouvez effectuer une recherche binaire pour une plage de temps comme le fait mon Python ici *. Dans le cas du fichier à longueur d'enregistrement fixe) , c'est vraiment facile. Vous cherchez simplement linelength * linecount
caractères dans le fichier.
* Je continue de vouloir publier une autre mise à jour de ce script. Peut-être que j'y arriverai un de ces jours.
J'ai découvert l'utilisation suivante de sed
sed -n '10000000,+20p' filename
J'espère que c'est utile à quelqu'un!
C'est la première fois que je publie ici! Quoi qu'il en soit, celui-ci est facile. Supposons que vous souhaitiez extraire la ligne 8872 de votre fichier appelé file.txt. Voici comment procéder:
cat -n fichier.txt | grep '^ * 8872'
Maintenant, la question est de trouver 20 lignes après cela. Pour ce faire, vous devez
cat -n fichier.txt | grep -A 20 '^ * 8872'
Pour les lignes autour ou avant voir les drapeaux -B et -C dans le manuel grep.
Utilisez la commande suivante pour obtenir la plage particulière de lignes
awk 'NR < 1220974{next}1;NR==1513793{exit}' debug.log | tee -a test.log
Voici debug.log est mon fichier qui se compose d'un manque de lignes et j'ai utilisé pour imprimer les lignes du numéro de ligne 1220974 à 1513793 dans un fichier test.log. espérons qu'il sera utile pour capturer la gamme de lignes.
La réponse sed de Dennis est la voie à suivre. Mais en utilisant juste la tête et la queue, sous bash:
middle () {head -n $ [$ 1 + $ 2] | queue -n $ 2; }
Cela scanne les premières lignes de 1 $ + 2 $ deux fois, c'est donc bien pire que la réponse de Dennis. Mais vous n'avez pas besoin de vous souvenir de toutes ces lettres sed pour l'utiliser ....
A Ruby version oneliner.
Ruby -pe 'next unless $. > 10000000 && $. < 10000020' < filename.txt
Cela peut être utile à quelqu'un. Les solutions avec "sed" fournies par Dennis et Dox sont très agréables, même parce qu'elles semblent plus rapides.
Perl est roi:
Perl -ne 'print if ($. == 10000000 .. $. == 10000020)' filename
Si vous connaissez les numéros de ligne, dites que vous voulez obtenir les lignes 1, 3 et 5 d'un fichier, dites/etc/passwd:
Perl -e 'while(<>){if(++$l~~[1,3,5]){print}}' < /etc/passwd
Vous pouvez utiliser 'nl'.
nl filename | grep <line_num>
Par exemple, cet awk imprimera des lignes entre 20 et 40
awk '{if ((NR> 20) && (NR <40)) affiche $ 0}'/etc/passwd