Il y a souvent des fois que je grep -n fichier whatev pour trouver ce que je cherche. Disons que la sortie est
1234: whatev 1
5555: whatev 2
6643: whatev 3
Si je veux ensuite extraire les lignes entre 1234 et 5555, existe-t-il un outil pour le faire? Pour les fichiers statiques, j'ai un script qui fait wc -l du fichier, puis fait le calcul pour le diviser avec tail & head mais cela ne fonctionne pas si bien avec les fichiers journaux qui sont constamment écrits.
Essayez d'utiliser sed comme mentionné sur http://linuxcommando.blogspot.com/2008/03/using-sed-to-extract-lines-in-text-file.html . Par exemple, utilisez
sed '2,4!d' somefile.txt
pour imprimer de la deuxième ligne à la quatrième ligne de somefile.txt. (Et n'oubliez pas de vérifier http://www.grymoire.com/Unix/Sed.html , sed est un merveilleux outil.)
La commande suivante fera ce que vous avez demandé "extraire les lignes entre 1234 et 5555" dans someFile.
sed -n '1234,5555p' someFile
Si je comprends bien, vous voulez trouver un modèle entre deux numéros de ligne. L'awk one-liner pourrait être
awk '/whatev/ && NR >= 1234 && NR <= 5555' file
Vous n'avez pas besoin d'exécuter grep
suivi de sed
.
Perl one-liner:
Perl -ne 'if (/whatev/ && $. >= 1234 && $. <= 5555') {print}' file
Les numéros de ligne sont OK si vous pouvez garantir la position de ce que vous voulez. Au fil des ans, ma saveur préférée a été quelque chose comme ceci:
sed "/First Line of Text/,/Last Line of Text/d" filename
qui supprime toutes les lignes de la première ligne correspondante à la dernière correspondance, y compris ces lignes.
Utilisez sed - n avec "p" au lieu de "d" pour imprimer ces lignes à la place. Beaucoup plus utile pour moi, car je ne sais généralement pas où sont ces lignes.
Mettez-le dans un fichier et rendez-le exécutable:
#!/bin/bash
start=`grep -n $1 < $3 | head -n1 | cut -d: -f1; exit ${PIPESTATUS[0]}`
if [ ${PIPESTATUS[0]} -ne 0 ]; then
echo "couldn't find start pattern!" 1>&2
exit 1
fi
stop=`tail -n +$start < $3 | grep -n $2 | head -n1 | cut -d: -f1; exit ${PIPESTATUS[1]}`
if [ ${PIPESTATUS[0]} -ne 0 ]; then
echo "couldn't find end pattern!" 1>&2
exit 1
fi
stop=$(( $stop + $start - 1))
sed "$start,$stop!d" < $3
Exécutez le fichier avec des arguments (REMARQUE: le script ne gère pas les espaces dans les arguments!):
Pour utiliser avec votre exemple, utilisez des arguments: 1234 5555 myfile.txt
Comprend des lignes avec un motif de démarrage et d'arrêt.
Si vous voulez des lignes au lieu de plages de lignes, vous pouvez le faire avec Perl: par exemple. si 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