J'aimerais imprimer une seule ligne directement après une ligne contenant un motif correspondant. Ma version de sed
ne prendra pas la syntaxe suivante (elle explose sur +1p
.), Ce qui semble être une solution simple:
sed -n '/ABC/,+1p' infile
Je suppose que awk
serait préférable pour le traitement multiligne, mais je ne sais pas comment le faire.
Ne jamais utiliser le mot "modèle" car il est très ambigu. Utilisez toujours "string" ou "regexp" (ou dans le "motif globbing" de Shell), quel que soit le mot que vous entendez vraiment.
La réponse spécifique que vous voulez est:
awk 'f{print;f=0} /regexp/{f=1}' file
ou en spécialisant la solution plus générale du nième enregistrement après une expression rationnelle (idiome "c" ci-dessous):
awk 'c&&!--c; /regexp/{c=1}' file
Les expressions suivantes décrivent comment sélectionner une plage d'enregistrements en fonction d'une expression rationnelle spécifique:
a) Imprimez tous les enregistrements de certaines expressions rationnelles:
awk '/regexp/{f=1}f' file
b) Imprimez tous les enregistrements après une expression rationnelle:
awk 'f;/regexp/{f=1}' file
c) Imprimez le Nième enregistrement après une expression rationnelle:
awk 'c&&!--c;/regexp/{c=N}' file
d) Imprimer tous les enregistrements sauf le Nième après une expression rationnelle:
awk 'c&&!--c{next}/regexp/{c=N}1' file
e) Imprimez les N enregistrements après une expression rationnelle:
awk 'c&&c--;/regexp/{c=N}' file
f) Imprimez tous les enregistrements sauf les N après une expression rationnelle:
awk 'c&&c--{next}/regexp/{c=N}1' file
g) Imprimez les N enregistrements de certaines expressions rationnelles:
awk '/regexp/{c=N}c&&c--' file
J'ai changé le nom de la variable de "f" pour "trouvé" en "c" pour "compte", où Est approprié car c'est plus représentatif de ce que la variable est réellement.
C'est la ligne après qui correspond dans laquelle vous êtes intéressant, non? Dans sed, cela pourrait être accompli comme suit:
sed -n '/ABC/{n;p}' infile
Vous pouvez également choisir l’optionAde grep.
-A NUM, Print NUM lines of trailing context after matching lines.
Par exemple, étant donné le fichier d'entrée suivant:
foo
bar
baz
bash
bongo
Vous pouvez utiliser les éléments suivants:
$ grep -A 1 "bar" file
bar
baz
$ sed -n '/bar/{n;p}' file
baz
J'espère que cela pourra aider.
J'avais besoin d'imprimer TOUTES les lignes après le motif (ok Ed, REGEX), alors j'ai choisi celui-ci:
sed -n '/pattern/,$p' # prints all lines after ( and including ) the pattern
Mais puisque je voulais imprimer toutes les lignes APRES (et exclure le motif)
sed -n '/pattern/,$p' | tail -n+2 # all lines after first occurrence of pattern
Je suppose que dans votre cas, vous pouvez ajouter un head -1
à la fin
sed -n '/pattern/,$p' | tail -n+2 | head -1 # prints line after pattern
version awk:
awk '/regexp/ { getline; print $0; }' filetosearch
Si le motif correspond, copiez la ligne suivante dans le tampon de motifs, supprimez un retour, puis quittez - l’effet secondaire consiste à imprimer.
sed '/pattern/ { N; s/.*\n//; q }; d'
En fait, sed -n '/pattern/{n;p}' filename
échouera si les pattern
correspondent aux lignes continuous
:
$ seq 15 |sed -n '/1/{n;p}'
2
11
13
15
Les réponses attendues devraient être:
2
11
12
13
14
15
Ma solution est:
$ sed -n -r 'x;/_/{x;p;x};x;/pattern/!s/.*//;/pattern/s/.*/_/;h' filename
Par exemple:
$ seq 15 |sed -n -r 'x;/_/{x;p;x};x;/1/!s/.*//;/1/s/.*/_/;h'
2
11
12
13
14
15
Explique:
x;
: au début de chaque ligne de l'entrée, utilisez la commande x
pour échanger le contenu dans pattern space
& hold space
./_/{x;p;x};
: si pattern space
, qui est en réalité le hold space
, contient _
(il s’agit simplement d’un indicator
indiquant si la dernière ligne correspondait à pattern
ou non), utilisez x
pour échanger le contenu réel de current line
en pattern space
, utilisez p
pour imprimer current line
, x
pour récupérer cette opération. x
: récupérer le contenu dans pattern space
et hold space
./pattern/!s/.*//
: si current line
ne correspond PAS à pattern
, ce qui signifie que nous ne devrions PAS imprimer la ligne suivante, utilisez ensuite la commande s/.*//
pour supprimer tout le contenu de pattern space
./pattern/s/.*/_/
: si current line
correspond à pattern
, ce qui signifie que nous devrions imprimer la ligne suivante, alors nous devons définir un indicator
pour indiquer à sed
d'imprimer la ligne NEXT, utilisez donc s/.*/_/
pour remplacer tout le contenu de pattern space
par un _
(la deuxième commande sera utilisée). de juger si la dernière ligne correspond à la variable pattern
ou non).h
: écrase le hold space
avec le contenu dans pattern space
; alors, le contenu dans hold space
est ^_$
, ce qui signifie que current line
correspond à la pattern
ou ^$
, ce qui signifie que current line
ne correspond PAS à la pattern
.s/.*/_/
, le pattern space
ne peut PAS correspondre à /pattern/
; le s/.*//
DOIT donc être exécuté!Cela pourrait fonctionner pour vous (GNU sed):
sed -n ':a;/regexp/{n;h;p;x;ba}' file
Utilisez l'option -n
de type seds grep et si la ligne actuelle contient l'expression rationnelle requise, remplacez la ligne actuelle par la suivante, copiez cette ligne dans l'espace de conservation (HS), imprimez la ligne, échangez l'espace de modèle (PS) pour le HS et répéter.