2010-04-12 7 views
5

J'ai un fichier qui est similaire à ceci:Bash: (peut-être sed) Extrait Range avec Expressioin régulier

<many lines of stuff> 
SUMMARY: 
<some lines of stuff> 
END OF SUMMARY 

Je veux extraire juste les choses entre SUMMARY et END OF SUMMARY. Je pense que je peux le faire avec sed mais je ne sais pas comment. Je sais que je peux modifier les choses entre les deux avec:

sed "/SUMMARY/,/END OF SUMMARY/ s/replace/with/" fileName 

(Mais je ne sais pas comment extraire ce genre de choses).

Je suis Bash sur Solaris.

Répondre

8
sed -n "/SUMMARY/,/END OF SUMMARY/p" fileName 
+1

Cela correspond aussi: .... RÉSUMÉ .... FIN DU RÉSUMÉ Ajout «^» exiger correspondant à la chaîne NULL au début de l'espace de modèle: -n sed «/^ RESUME /,/^ FIN DU SOMMAIRE/p " –

+1

Si vous faites cela, c'est probablement une bonne idée d'ajouter un marqueur de fin de ligne.Soit: 'sed -n"/^ SOMMAIRE $ /,/^ FIN DU SOMMAIRE $/p "' – sixtyfootersdude

1

Si Perl est bien vous pouvez utiliser:

perl -e 'print $1 if(`cat FILE_NAME`=~/SUMMARY:\n(.*?)END OF SUMMARY/s);' 
+0

Ouais, j'aime perl aussi, mais mon équipe a plus de personnes seddy. – sixtyfootersdude

+0

J'aime aussi Perl, mais celui-ci ressemble plus à un travail pour sed. –

0

Vous pouvez le faire avec awk:

$ echo 'many 
lines 
of 
stuff 
SUMMARY: 
this is the summary 
over two lines 
END OF SUMMARY' | awk ' 
    BEGIN    {e=0} 
    /^END OF SUMMARY$/ {e=0} 
         {if (e==1) {print}} 
    /^SUMMARY:$/  {e=1}' 

qui délivre:

this is the summary 
over two lines 

Pas tous Implementat les ions de awk nécessiteront la clause BEGIN mais j'aime toujours inclure une initialisation explicite.

Il fonctionne en utilisant un indicateur d'écho (e) pour décider si vous êtes dans la section récapitulative ou non.

1

Si vous ne souhaitez pas imprimer les lignes de marquage:

sed '1,/SUMMARY/d;/END OF SUMMARY/,$d' filename 
0

Sur Solaris, utilisez nawk

#!/bin/bash 
nawk ' 
/SUMMARY/{ 
gsub(".*SUMMARY:",""); 
f=1 
} 
/END OF SUMMARY/{f=0; 
gsub("END OF SUMMARY.*","") 
}f' file 

sortie

$ cat file 
1 2 3 <many lines of stuff> 
4 5 6 SUMMARY: 7 8 9 
<some lines of stuff> 
END OF SUMMARY blah 
blah 

$ ./shell.sh 
7 8 9 
<some lines of stuff> 
1

Cela devrait fonctionner à l'aide (FreeBSD) sed aussi:

sed -E -n -e '/^SUMMARY:/,/^END OF SUMMARY/{ /^SUMMARY:/d; /^END OF SUMMARY/d; p;}' file.txt 
+0

Quel est l'avantage de cela sur 'sed -n"/^ SOMMAIRE $ /,/^ FIN DU SOMMAIRE $/p "fileName"? – sixtyfootersdude

0

Voici encore une autre version sed faire juste une impression sur plusieurs lignes & quit (qui peut convenir à extraire une gamme de lignes à partir d'un fichier volumineux):

sed -E -n -e '/^SUMMARY:$/{n;h;};/^END OF SUMMARY$/!H;/^END OF SUMMARY$/{g;p;q;}' fileName | sed 1d 

Pour un joli script sed multi-ligne bien expliqué voir:

http://ilfilosofo.com/blog/2008/04/26/sed-multi-line-search-and-replace/

+0

Hum. J'ai regardé cette référence mais je pense toujours qu'il est préférable de faire des remplacements en utilisant une gamme plutôt que des tampons. Intéressé d'entendre si/pourquoi vous pensez que les tampons sont meilleurs. – sixtyfootersdude