grep

2010-10-20 8 views
1

J'ai deux requêtesgrep

  1. Je fais grep et obtenir le numéro de ligne du fichier d'entrée. Je veux récupérer un ensemble de lignes avant et après le numéro de ligne du fichier d'entrée et rediriger vers un fichier/tmp/testout. Comment puis-je le faire. J'ai un numéro de ligne 10000, 20000 Je veux récupérer les lignes entre 10000 et 20000 du fichier d'entrée et rediriger vers un fichier/tmp/testout. Comment puis-je doi il

+1

Si vous n'êtes pas au courant, il existe un site de questions-réponses unix/linux: http://unix.stackexchange.com/ –

+0

Le site super-utilisateur est une autre alternative. –

+0

Et il y a un très bon site appelé StackOverflow pour lequel c'est une question parfaitement adaptée! –

Répondre

8

pour C grep est l'option avant droite

pour la 2e question essayez ceci!

sed -n "100000,20000p" bar.txt > foo.txt 
+0

Comme noté dans un commentaire à une autre question, votre réponse ne fonctionne qu'avec GNU grep - POSIX grep n'inclut pas l'option '-C' (ou '-A 'ou' -B 'options). –

1

Voir head et/ou tail.

Par exemple:

head -n 20000 <input> | tail -n 10000 > /tmp/testout 

tandis que l'argument de la queue est (20000-10000).

1

Si vous utilisez GNU grep, vous pouvez fournir -B et -A pour obtenir des lignes avant et après la correspondance avec grep.

E.g.

grep -B 5 -A 10 SearchString File 

donnera l'impression de chaque ligne correspondant à SearchString à partir de File plus 5 lignes avant et 10 lignes après la ligne correspondante.

Pour l'autre partie de votre question, vous pouvez utiliser head/tail ou sed. S'il vous plaît voir d'autres réponses pour plus de détails.

+1

Uniquement dans GNU grep - POSIX grep n'inclut pas les options '-A' ou '-B'. Comme un tag est 'linux', vous n'obtenez pas de vote négatif, mais comme un autre tag est 'unix', je ne suis pas sûr du vote positif non plus. De plus, cela ne répond que Q1, pas Q2. –

+0

@Jonathan: Juste point et merci d'avoir laissé un commentaire dans tous les cas. Je n'ai pas répondu à la deuxième partie car c'était déjà couvert. Je vais mettre à jour la question pour refléter cela. –

2

Vous souhaitez examiner les options -A -B et -C de grep. Voir man grep pour plus d'informations

-A NUM, --after-context=NUM 
      Print NUM lines of trailing context after matching lines. 
      Places a line containing -- between contiguous groups of 
      matches. 

    -B NUM, --before-context=NUM 
      Print NUM lines of leading context before matching lines. 
      Places a line containing -- between contiguous groups of 
      matches. 

    -C NUM, --context=NUM 
      Print NUM lines of output context. Places a line containing -- 
      between contiguous groups of matches. 

Pour rediriger la sortie, procédez comme suit: grep "your pattern" yourinputfile > /tmp/testout

0

Pour la partie 2, awk vous permettra d'imprimer une gamme de lignes ainsi:

awk 'NR==10000,NR==20000{print}{}' inputfile.txt >/tmp/testout 

Cette donne essentiellement une gamme basée sur le numéro d'enregistrement NR. Pour la partie 1, le contexte grep peut être obtenu en utilisant les commutateurs --after-context=X et --before-context=X. Si vous utilisez un grep qui ne le permet pas, vous pouvez définir un script awk en fonction de la réponse à la partie 2 ci-dessus.

+0

'NR> = 10000 {print} NR> 20000 {exit}' – ghostdog74

0

pour voir le avant et après: (3 lignes avant et 3 lignes après)

grep -C3 foo bar.txt 

la deuxième question:

head -20000 bar.txt | tail -10000 > foo.txt 
0

vous pouvez faire ces avec juste awk, par exemple l'affichage 2 lignes avant et après "6", et la plage d'affichage de linenumber 4 à 8

$ cat file 
1 
2 
3 
4 
5 
6 
7 
8 
9 
10 

$ awk 'c--&&c>=0{print "2 numbers below 6: "$0};/6/{c=2;for(i=d;i>d-2;i--)print "2 numbers above 6: "a[i];delete a}{a[++d]=$0} NR>3&&NR<9{print "With range: ->"$0}' file 
With range: ->4 
With range: ->5 
2 numbers above 6: 5 
2 numbers above 6: 4 
With range: ->6 
2 numbers below 6: 7 
With range: ->7 
2 numbers below 6: 8 
With range: ->8 
0

Si votre grep n'a pas -A, -B et -C, cette commande sed peut travailler pour vous:

sed -n '1bb;:a;/PATTERN/{h;n;p;H;g;bb};N;//p;:b;99,$D;ba' inputfile > outputfile 

PATTERN est le Regula r expression votre recherche et 99 est un plus grand que le nombre de lignes de contexte que vous voulez (équivalent à -C 98).

Il fonctionne en gardant une fenêtre de lignes en mémoire et lorsque l'expression régulière correspond, les lignes capturées sont sorties.

Si votre sed n'aime pas des points-virgules et préfère -e, cette version peut travailler pour vous:

sed -n -e '1bb' -e ':a' -e '/PATTERN/{h' -e 'n' -e 'p' -e 'H' -e 'g' -e 'bb}' -e 'N' -e '//p' -e ':b' -e '99,$D' -e 'ba' inputfile > outputfile 

Pour votre sortie de plage de ligne, cela fonctionne et se terminera un peu plus rapidement s'il y a grand nombre de lignes après la fin de la gamme:

sed -n '100000,20000p;q' inputfile > outputfile 

ou

sed -n -e '100000,20000p' -e 'q' inputfile > outputfile