Le fichier d'entrée 1 est:
dog 123 4335
cat 13123 23424
deer 2131 213132
bear 2313 21313
Je donne à la correspondance le motif de dans other file
(comme à dog 123 4335
partir de fichier2).
Je fais correspondre le motif de la ligne dog 123 4335
et après avoir imprimé toutes les lignes sans ligne de correspondance, ma sortie est:
cat 13123 23424
deer 2131 213132
bear 2313 21313
Si uniquement utiliser sans adresse de ligne, utilisez uniquement le motif, par exemple, 1s
comment faire correspondre et imprimer les lignes?
text-processing
sed
grep
loganaayahee
la source
la source
Réponses:
En supposant que vous souhaitiez faire correspondre toute la ligne à votre modèle, avec GNU
sed
, cela fonctionne:Équivalent standard:
Avec l'entrée suivante (
infile
):La sortie est:
Explication:
/^dog 123 4335$/
recherche le motif désiré.:a; n; p; ba;
est une boucle qui extrait une nouvelle ligne de input (n
), l’imprime (p
) et la ramène à l’étiquette a:a; ...; ba;
.Mise à jour
Voici une réponse qui se rapproche de vos besoins, c'est-à-dire un motif dans file2, en allant de fichier1
Les commandes grep et cut incorporées trouvent la première ligne contenant un motif de fichier2, ce numéro de ligne plus un est transmis à la fin, le plus un permettant de sauter la ligne contenant le motif.
Si vous voulez commencer à partir du dernier match au lieu du premier, ce serait:
Notez que toutes les versions de tail ne prennent pas en charge la notation plus.
la source
sed -n '/^dog 123 4335$/ { :a; p; n; ba; }' infile
(avec le p et le n commutés) inclut avec succès la ligne qui correspond également.Si vous avez un fichier raisonnablement court,
grep
seul pourrait fonctionner:5000 est juste ce que je pense de "raisonnablement court", car
grep
trouve la première correspondance et la sort avec les 5000 prochaines lignes (le fichier n'en a pas besoin souvent). Si vous ne voulez pas le match lui-même, vous devrez le couper, par exempleSi vous ne voulez pas le premier mais le dernier match comme délimiteur, vous pouvez utiliser ceci:
Cette ligne lit
animals.txt
dans l’ordre inverse des lignes et en sort jusqu’à la ligne inclusedog 123 4335
, puis s’inverse de nouveau pour rétablir le bon ordre.Encore une fois, si vous n'avez pas besoin de la correspondance dans le résultat, ajoutez la queue. (Vous pouvez également compliquer l’expression sed pour se débarrasser de son tampon avant de quitter.)
la source
Dans la pratique, j'utiliserais probablement la réponse d'Aet3miirah la plupart du temps et celle d' Alexey est merveilleuse lorsque l'on souhaite naviguer à travers les lignes (cela fonctionne également avec
less
). OTOH, j'aime vraiment une autre approche (qui est un peu la réponse inversée de Gilles :Lorsqu’il est appelé avec l’
-n
indicateur,sed
n’imprime plus par défaut les lignes qu’il traite. Ensuite, nous utilisons un formulaire à 2 adresses qui dit d’appliquer une commande depuis la ligne correspondant/dog 123 4335/
à la fin du fichier (représenté par$
). La commande en question estp
, qui affiche la ligne en cours. Donc, cela signifie "imprimer toutes les lignes depuis celle qui correspond/dog 123 4335/
jusqu'à la fin".la source
dog
ligne, ce qui n'est pas voulu ici.sed -n '/dog 123 4335/,$p' | tail -n +2
éliminera aussi le matchSi vous avez besoin de lire le modèle depuis un fichier, remplacez-le par la commande sed. Si le fichier contient un motif sed:
Si le fichier contient une chaîne littérale à rechercher, citez tous les caractères spéciaux. Je suppose que le fichier contient une seule ligne.
Si vous voulez que la correspondance soit toute la ligne, pas seulement une sous-chaîne, insérez le motif dans
^…$
.la source
sed
a0,/dog.../d
pour cela.$ more +/"dog 123 4335" file1
la source
less
.tac
.+
été remplacé par-p
dans POSIX 7: pubs.opengroup.org/onlinepubs/9699919799/utilities/more.html mais pas encore implémenté dans util-linux 2.20.1. Et cela imprime aussiskipping..
et quelques nouvelles lignes supplémentaires (à stderr je pense, donc ça pourrait aller).Avec
awk
:la source
Une façon d'utiliser awk:
où fichier2 contient vos modèles de recherche. Tout d'abord, tout le contenu de file2 est stocké dans le tableau "a". Lorsque le fichier1 est traité, chaque ligne est comparée au tableau et imprimée uniquement si elle n’est pas présente.
la source
Si l'entrée est un fichier régulier lseekable :
Avec GNU
grep
:Avec
sed
:Un GNU
grep
appelé w / l’-m
option quittera l’entrée lors du match - et laissera son entrée (lseekable) fd immédiatement après le point où il a trouvé son dernier match. Donc, appelergrep
w /-m1
trouve la première occurrence d’un motif dans un fichier et laisse l’offset en entrée précisément au bon endroit pourcat
tout écrire après la première correspondance du motif dans un fichier sur la sortie standard.Même sans GNU,
grep
vous pouvez faire exactement la même chose avec un compatible POSIXsed
- quand voussed
q
spécifiez, il est spécifié de laisser son décalage d'entrée là où il le fait. GNUsed
n'est pas conforme aux normes de cette manière, cependant, et donc ce qui précède ne fonctionnera probablement pas avec GNU àsed
moins que vous ne l'appeliez avec son-u
commutateur.la source
sed
partage de flux démontré ici ne constitue pas spécialement (bien que, oui, la norme référencée donne spécifiquement l'exemple ensed
tant qu'utilitaire capable de fonctionner) du flux de travaux de forme libre et de coopération conditionnelle indiqué. notamment, tous les utilitaires standard sont conçus et spécifiés pour coopérer et ainsi partager les positions de curseur des flux d’entrée sans que le lecteur suivant ne manque de traitement.grep -q
devrait le faire; tranquillementgrep
devrait revenir dès qu'une correspondance est trouvée dans l'entrée, et tout reste d'entrée ne devrait pas, selon la norme, être consommé par défaut.Ma réponse à la question dans le sujet, sans stocker le motif dans un deuxième fichier. Voici mon fichier de test:
GNU sed:
Perl:
Variante Perl avec motif dans un fichier:
la source
Avec
ed
:Cela envoie une
p
commande rint à ed dans une chaîne ici; la commande d'impression est limitée à un après (+1
) ladog 123 4335
correspondance jusqu'à la fin du fichier ($
).la source
Si la création d'un fichier temporaire ne vous dérange pas et si vous en avez
csplit
, cela fonctionne:Note
file1
est le fichier d'entrée etfile2
le fichier de motif (comme indiqué dans la question).La forme longue de la commande ci-dessus est:
c'est à dire,
csplit
sans leprefix
drapeau ci-dessus, le fichier serait crééxx00
(le préfixe étantxx
et le suffixe étant00
). Avec le drapeau ci-dessus, il crée le fichierfile1_00
. Sans l'quiet
indicateur, il affiche la taille du fichier de sortie (taille du fichier résultant).la source
Puisque awk n'est pas expressément interdit, voici mon offre en supposant que "chat" est la contrepartie.
la source
Une autre façon de le dire est "comment supprimer toutes les lignes de la première jusqu'à la correspondance (y compris)", et cela peut être
sed
écrit ainsi:la source
sed -e '0,/MATCH PATTERN/d'
alors?