Imprimer la ligne après la nième occurrence d'une correspondance

8

Je cherche à afficher la ligne 4598 dans le fichier suivant. En fait, je veux afficher la ligne APRÈS la nième occurrence d'une correspondance. Dans ce cas, la ligne après la 3ème occurrence de <Car>. Comment dois-je procéder?

<Car>
10456
</Car>
<Car>
70192
</Car>
<Car>
4598
</Car>
DJ180
la source
1
Bien qu'il soit possible d'obtenir ce que vous souhaitez utiliser sed, awkou même grep, il est conseillé d'utiliser un analyseur XML.
devnull
XML n'a été utilisé que pour l'exemple, le texte peut être de n'importe quel format
DJ180

Réponses:

10
awk -v n=3 '/<Car>/ && !--n {getline; print; exit}'

Ou:

awk '/<Car>/ && ++n == 3 {getline; print; exit}'

Pour passer le modèle de recherche en tant que variable:

var='<car>'
PATTERN="$var" awk -v n=3 '
  $0 ~ ENVIRON["PATTERN"] && ++n == 3 {getline; print; exit}'

Ici, l'utilisation ENVIRONau lieu de -vas -vdéveloppe les séquences d'échappement antislash et les antislashs sont souvent trouvés dans les expressions régulières (il faudrait donc les doubler -v).

GNU awk4.2 ou supérieur vous permet d'affecter des variables en tant que regexps typés forts . Tant que son mode POSIX n'est pas activé (par exemple via la $POSIXLY_CORRECTvariable d'environnement, vous pouvez faire:

# GNU awk 4.2 or above only, when not in POSIX mode
gawk -v n=3 -v pattern="@/$var/" '
  $0 ~ pattern && ++n == 3 {getline; print; exit}'
Stéphane Chazelas
la source
Comment passer le modèle de recherche également comme variable dans la commande ci-dessus
WanderingMind
@WanderingMind, voir modifier.
Stéphane Chazelas
4

En voici un:

perl -ne 'print && exit if $c==3; $c++ if /<Car>/;' file 

Avec GNU grep, vous pouvez également analyser sa sortie comme:

grep -A 1 -m 3 '<Car>' file | tail -n 1

De man grep:

-A NUM, --after-context=NUM
          Print NUM lines of trailing context after matching lines.  
          Places a line containing a group separator (--) between 
          contiguous  groups  of  matches.          
-m NUM, --max-count=NUM
          Stop reading a file after NUM matching lines.  
terdon
la source
3

Avec GNU awkvous pouvez faire:

gawk -v RS='</Car>' 'NR==3 && $0=$2' inputFile
jaypal singh
la source
1

Voici une autre façon avec sed:

sed -n '/<Car>/{x;/.\{2\}/{x;$!{n;p};q};s/.*/&./;x}' infile

Cela utilise l'espace d'attente pour compter.
Chaque fois qu'il rencontre une ligne correspondant, <Car>il xchange de tampon et vérifie s'il y a exactement N-1 occurrences d'un caractère dans le tampon de maintien. Si la vérification réussit, elle xchange à nouveau, et si elle n'est pas sur la dernière ligne, elle tire sur la nligne ext et pimprime l'espace de motif puis se qferme. Sinon, cela ajoute simplement un autre caractère .à l'espace d'attente et e xchange de nouveau.

don_crissti
la source
0

Voici une solution de ligne de commande simple.

grep -F -A1 '<Car>' filename | grep -E -v '<Car>|--' | tail -n +3 |head -n +1

Si vous modifiez la valeur de +3 après tail, vous pouvez spécifier n'importe quelle nième ligne.

bsd
la source
Vous ne savez pas pourquoi vous avez ajouté les balises, sed, awk, etc. Si vous voulez une solution utilisant une application spécifique, un utilitaire, vous devez le spécifier en question ou en titre.
bsd