Je suppose que tout le monde connaît les utilitaires de ligne de commande Linux utiles head
et tail
. head
vous permet d'imprimer les X premières lignes d'un fichier, tail
fait la même chose mais affiche la fin du fichier. Qu'est-ce qu'une bonne commande pour imprimer au milieu d'un fichier? quelque chose comme middle --start 10000000 --count 20
(imprimer les lignes 10'000'000 à 10'000'010).
Je cherche quelque chose qui traitera efficacement les gros fichiers. J'ai essayé tail -n 10000000 | head 10
et c'est horriblement lent.
Réponses:
Vous pourriez peut-être accélérer cela un peu comme ceci:
Dans ces commandes, l'option
-n
amènesed
à « supprimer l' impression automatique de l' espace de motif ». Lap
commande "imprime le motif actuel" et laq
commande "Quitte immédiatement le script sed sans traitement supplémentaire ..." Les guillemets proviennent de lased
man
page .Au fait, votre commande
commence à la dix millionième ligne à partir de la fin du fichier, tandis que votre commande "moyenne" semble commencer au dix millionième à partir du début, ce qui équivaut à:
Le problème est que pour les fichiers non triés avec des lignes de longueur variable, tout processus doit passer par le décompte des fichiers. Il n'y a aucun moyen de raccourcir cela.
Toutefois, si le fichier est trié (un fichier journal avec des horodatages, par exemple) ou s'il comporte 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 plusieurs fois, comme le fait mon script Python ici *. Dans le cas du fichier à longueur d'enregistrement fixe, c'est très simple. Vous recherchez simplement des
linelength * linecount
caractères dans le fichier.* Je continue à vouloir publier une autre mise à jour de ce script. Peut-être que je vais en parler un de ces jours.
la source
sed
version de Charlesmiddle
fonction:middle() { local s=$1 c=$2; shift 2; sed -n "$s,$(($s + $c -1))p; $(($s + $c))q" "$@"; }
. Il gérera plusieurs arguments de fichiers, noms de fichiers avec des espaces, etc. Plusieurs fichiers sont traités ensemble comme s'ils avaient été traités de la même manière que d'habitudesed
(de sorte que le milieu 1000 100 fichier1 fichier2 s'étendrait de la fin du premier fichier au début du second si le premier a moins de 1100 lignes).middle startline count filename
ou plusieurs noms de fichiers:middle startline count file1 file2 file3
ou avec une redirection:middle startline count < filename
ou dans un tuyau: nombresome_command |
moyen de lignes de départ, oucat file* | middle startline count
J'ai découvert l'utilisation suivante de
sed
J'espère que c'est utile à quelqu'un!
la source
sed -n
argument, ce qui le rend très lisible.extract_lines(){sed -n "$1,+$2p" <file>}
qui écrit sur stdout.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ée fichier.txt. Voici comment vous le faites:
cat -n fichier.txt | grep '^ * 8872'
Maintenant, la question est de trouver 20 lignes après cela. Pour ce faire, vous faites
cat -n fichier.txt | grep -A 20 '^ * 8872'
Pour les lignes autour ou avant, voir les drapeaux -B et -C dans le manuel grep.
la source
cat -n file.txt | grep '^ *1'
donne toutes les lignes qui ont 1 sur leur côté droit. Comment sortir la ligne 1 avec cette technique? Je sais que je peux diriger -n 1 .... mais comment utiliser grep?La réponse séduite de Dennis est la voie à suivre. Mais en utilisant juste la tête et la queue, sous bash:
Cela balaye deux fois les premières lignes à 1 $ + 2 $, ce qui est 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 ...
la source
$[...]
est déconseillée, du moins en Bash. En outre, il vous manque un paramètre de fichier.middle 10 10 < /var/log/auth.log
.Utilisez la commande suivante pour obtenir la plage de lignes particulière
Ici debug.log est mon fichier qui consiste en un manque de lignes et j’imprimais les lignes de 1220974 à 1513793 dans un fichier test.log. espérons que cela vous aidera à capturer la gamme de lignes.
la source
Une version ruby oneliner.
Cela peut être utile à quelqu'un. Les solutions avec 'sed' fournies par Dennis et Dox sont très sympas, même parce que cela semble plus rapide.
la source
Vous pouvez utiliser 'nl'.
la source
Par exemple, ce awk imprimera des lignes entre 20 et 40
la source
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:
la source
Perl est roi:
la source