Utilisation du système d'exploitation OPEN STEP 4.2 ... J'utilise actuellement la sed
commande suivante :
sed -n '1,/141.299.99.1/p' TESTFILE | tail -3
Cette commande trouvera une instance dans un fichier avec l'IP de 141.299.99.1 et inclura également 3 lignes avant ce qui est tout bon, à l'exception que je voudrais également trouver toutes les instances de l'IP et les 3 lignes avant et pas seulement le premier.
Réponses:
Voici une tentative d'émulation à l'
grep -B3
aide d'une fenêtre mobile sed, basée sur cet exemple GNU sed (mais avec un peu de chance, conforme POSIX - avec remerciement à @ StéphaneChazelas):Les deux premières expressions amorcent un tampon de modèle multi-lignes et lui permettent de gérer le cas de bord dans lequel il y a moins de 3 lignes de contexte précédent avant la première correspondance. L'expression du milieu (correspondance d'expression régulière) imprime une ligne en haut de la fenêtre jusqu'à ce que le texte de correspondance souhaité ait ondulé à travers le tampon de modèle. La finale fait
$!N;D
défiler la fenêtre d'une ligne sauf lorsqu'elle atteint la fin de la saisie.la source
-e
n'est pas spécifique à GNU. Pour être POSIX / portable, vous en avez besoin car il ne peut rien y avoir après}
(et vous en avez besoin;
avant).-e '1h;2,4{H;g;}' -e '1,3d'
? Je n'ai pas de système non GNU sur lequel tester (et le--posix
commutateur GNU sed ne semble pas s'en soucier).sed
du heirloom toolchest qui est un descendant du sed Unix traditionnel. La spécification POSIX / Unix poursed
est sur pubs.opengroup.org/onlinepubs/9699919799/utilities/sed.htmlgrep
fera un meilleur travail de ceci:Le
-B 3
moyen d'imprimer les trois lignes avant chaque match. Cela s'imprimera--
entre chaque groupe de lignes. Pour désactiver cela, utilisez--no-group-separator
également.L'
-B
option est également prise en charge par GNUgrep
et la plupart des versions BSD ( OSX , FreeBSD , OpenBSD , NetBSD ), mais ce n'est techniquement pas une option standard.la source
Avec
sed
vous pouvez faire une fenêtre coulissante.Ça le fait. Mais méfiez-vous
bash
du comportement fou de l'expansion!
même lorsqu'il est cité !!! dans la chaîne de commande de votre historique de commande pourrait le rendre un peu fou. Préfixez la commande avecset +H;
si vous trouvez que c'est le cas. Pour ensuite le réactiver (mais pourquoi ???), faites-leset -H
ensuite.Cela, bien sûr, ne s'appliquerait si vous étiez utilisez
bash
- bien que je ne crois pas que vous êtes. Je suis assez certain que vous travaillez aveccsh
- (qui se trouve être le shell dont le comportement insensébash
émule avec l'expansion de l'historique, mais peut-être pas aux extrêmes que le shell c a pris) . Donc , probablement un\!
devrait fonctionner. J'espère.Tout est du code portable: POSIX décrit ainsi ses trois opérateurs: (même s'il convient de noter que je n'ai confirmé que cette description existait déjà en 2001)
Donc, sur la première ligne, vous ajoutez une ligne supplémentaire à l'espace de motif, cela ressemble à ceci:
Ensuite, sur la première ligne et chaque ligne suivante - à l'exception de la toute dernière - vous ajoutez une autre ligne à l'espace de motif. Il ressemble donc à ceci:
Si votre adresse IP se trouve en vous,
P
imprimez jusqu'à la première nouvelle ligne, alors juste la ligne 1 ici. À la fin de chaque cycle, vous lesD
supprimez et recommencez avec ce qui reste. Le prochain cycle ressemble donc à:...etc. Si votre adresse IP se trouve sur l'un de ces trois, le plus ancien s'imprimera - à chaque fois. Vous n'avez donc que trois lignes d'avance.
Voici un petit exemple. Je vais faire imprimer un tampon de trois lignes pour chaque numéro se terminant par zéro:
Celui-ci est un peu plus compliqué que votre cas, car j'ai dû alterner entre la
0\n
nouvelle ligne ou la0$
fin de l'espace de motif pour ressembler davantage à votre problème - mais ils sont subtilement différents en ce sens que cela nécessite une ancre - ce qui peut être un peu difficile à faire car l'espace-modèle change constamment.J'ai utilisé les cas étranges de 10 et 52 pour montrer que tant que l'ancre est flexible, la sortie l'est également. De manière totalement portable, je peux obtenir les mêmes résultats en comptant plutôt sur l'algorithme et en faisant:
Et élargissez la recherche tout en restreignant ma fenêtre - de 0 à 9 et 0 et de 3 lignes à deux.
Quoi qu'il en soit, vous avez l'idée.
la source
sed '...' $filename
. Soit dit en passant - j'ai laissé dans les périodes de votre propre chaîne de recherche, mais ce ne sont pas en fait des périodes dans un modèle - celles-ci représentent n'importe quel caractère. Vous devriez probablement faireoct\.oct\.oct\.oct
pour leur échapper afin qu'ils ne correspondent qu'à des périodes.Puisque vous mentionnez que vous n'en avez pas la
-B
possibilitégrep
, vous pouvez utiliser Perl (par exemple) pour faire glisser une fenêtre de 4 lignes:La réponse de Ramesh fait la même chose avec
awk
.la source
Lorsque disponible, vous pouvez utiliser pcregrep :
la source
Vous pouvez implémenter la même approche de base que les autres réponses non grep dans le shell lui-même (cela suppose un shell relativement récent qui prend en charge
=~
):Alternativement, vous pouvez extraire le fichier entier dans un tableau:
la source
Si votre système ne prend pas en charge le
grep
contexte, vous pouvez essayer ack-grep à la place:ack
est un outil comme grep, optimisé pour les programmeurs.la source
perl
, vous pouvez utiliserack
.Dans cette
awk
solution, un tableau est utilisé qui contiendra toujours 3 lignes avant le motif actuel. Par conséquent, lorsque le motif est mis en correspondance, le contenu du tableau avec le motif actuel est imprimé.Essai
Après avoir exécuté la commande, la sortie est,
la source
Dans la plupart d'entre eux,
/141.299.99.1/
correspondra également (par exemple)141a299q99+1
ou141029969951
parce que.
dans une expression régulière peut représenter n'importe quel caractère.L' utilisation
/141[.]299[.]99[.]1/
est plus sûre et vous pouvez ajouter un contexte supplémentaire au début et à la fin de l'ensemble regexp pour vous assurer qu'il ne correspond pas3141.
,.12
,.104
, etc.la source