En utilisant awk
ou sed
comment puis-je sélectionner des lignes qui se produisent entre deux motifs de marqueurs différents? Il peut y avoir plusieurs sections marquées de ces modèles.
Par exemple: supposons que le fichier contienne:
abc
def1
ghi1
jkl1
mno
abc
def2
ghi2
jkl2
mno
pqr
stu
Et le modèle de départ est abc
et le modèle de fin est mno
donc, j'ai besoin de la sortie comme:
def1
ghi1
jkl1
def2
ghi2
jkl2
J'utilise sed pour faire correspondre le modèle une fois:
sed -e '1,/abc/d' -e '/mno/,$d' <FILE>
Existe-t-il un moyen sed
ou awk
de le faire à plusieurs reprises jusqu'à la fin du fichier?
awk '/abc/{a=1}/mno/{print;a=0}a' file
.awk '/abc/{a=1} a; /mno/{a=0}' file
- avec cela, mettre laa
condition avant le/mno/
nous lui faisons évaluer la ligne comme vraie (et l'imprimer) avant de la définira=0
. De cette façon, nous pouvons éviter d'écrireprint
.awk '/abc/,/mno/' file
awk '/abc/{flag=1}/mno/{flag=0}flag' file
devrait faire.awk 'flag; /PAT1/{flag=1; next} /PAT1/{flag=0}' file
ferait probablement .Utilisation
sed
:L'
-n
option signifie ne pas imprimer par défaut.Le modèle recherche les lignes contenant juste
abc
à justemno
, puis exécute les actions dans le{ ... }
. La première action supprime laabc
ligne; le second lamno
ligne; et lesp
imprime les lignes restantes. Vous pouvez assouplir les expressions régulières au besoin. Les lignes en dehors de la plage deabc
.. nemno
sont tout simplement pas imprimées.la source
-e
sed
doit s'exécuter. Si vous voulez ou devez utiliser plusieurs arguments pour inclure le script entier, vous devez utiliser-e
avant chacun de ces arguments; sinon, c'est facultatif (mais explicite).d
à toutes les lignes jusqu'au premier match, puis un autred
à toutes les lignes commençant par le deuxième match?Cela pourrait fonctionner pour vous (GNU sed):
Supprimez toutes les lignes sauf celles entre les lignes commençant
abc
etmno
la source
!d;//d
golfs 2 caractères mieux :-) stackoverflow.com/a/31380266/895245{//!b}
empêcheabc
etmno
d'être inclus dans la sortie, mais je ne peux pas comprendre comment. Pourriez-vous expliquer?//!b
lit si la ligne courante n'est ni l'une des lignes qui correspondent à la plage, coupez et donc imprimez ces lignes sinon toutes les autres lignes sont supprimées.golfs deux personnages mieux que ceux de ppotong
{//!b};d
Les barres obliques vides
//
signifient: "réutiliser la dernière expression régulière utilisée". et la commande fait la même chose que la plus compréhensible:Cela semble être POSIX :
la source
À partir des liens de la réponse précédente, celui qui l'a fait pour moi, fonctionnant
ksh
sous Solaris, était le suivant:1,/firstmatch/d
: de la ligne 1 jusqu'à la première recherchefirstmatch
, supprimez./secondmatch/,$d
: de la première occurrence desecondmatch
jusqu'à la fin du fichier, supprimer.la source
1,
) vient-il avant/firstmatch/
? Je suppose que cela pourrait également être formulé'/firstmatch/1,d;/secondmatch,$d'
?la source
quelque chose comme ça fonctionne pour moi:
file.awk:
en utilisant:
awk -f file.awk data
...edit: La solution O_o fedorqui est bien meilleure / plus jolie que la mienne.
la source
if (record=1)
devrait êtreif (record==1)
, c'est-à-dire double=
- voir les opérateurs de comparaison gawkRéponse de Don_crissti dans Afficher uniquement le texte entre 2 motifs correspondants ?
qui est beaucoup plus efficace que l'application d'AWK, voir ici .
la source
J'ai essayé d'
awk
imprimer des lignes entre deux motifs alors que pattern2 correspond également à pattern1 . Et la ligne pattern1 doit également être imprimée.par exemple source
devrait avoir une sortie de
Où pattern1 est
package BBB
, pattern2 estpackage \w*
. Notez que ceCCC
n'est pas une valeur connue et ne peut donc pas être mis en correspondance.Dans ce cas, ni @scai
awk '/abc/{a=1}/mno/{print;a=0}a' file
ni @fedorqui neawk '/abc/{a=1} a; /mno/{a=0}' file
fonctionnent pour moi.Enfin, j'ai réussi à le résoudre par
awk '/package BBB/{flag=1;print;next}/package \w*/{flag=0}flag' file
, hahaUn peu plus d'effort permet
awk '/package BBB/{flag=1;print;next}flag;/package \w*/{flag=0}' file
d'imprimer également la ligne pattern2, c'est-à-direla source