web-dev-qa-db-fra.com

sed: affiche uniquement le groupe correspondant

Je veux saisir les deux derniers chiffres (un int, un float; suivis par des espaces optionnels) et les imprimer uniquement.

Exemple:

foo bar <foo> bla 1 2 3.4

Devrait imprimer:

2 3.4

Jusqu'à présent, j'ai les éléments suivants:

sed -n  's/\([0-9][0-9]*[\ \t][0-9.]*[\ \t]*$\)/replacement/p' 

va me donner

foo bar <foo> bla 1 replacement

Cependant, si j'essaie de le remplacer par le groupe 1, toute la ligne est imprimée.

sed -n  's/\([0-9][0-9]*[\ \t][0-9.]*[\ \t]*$\)/\1/p' 

Comment puis-je imprimer uniquement la section de la ligne qui correspond à l'expression rationnelle du groupe?

112
mort

Faites correspondre la ligne entière, ajoutez donc un .* au début de votre expression rationnelle. Cela provoque le remplacement de toute la ligne par le contenu du groupe.

echo "foo bar <foo> bla 1 2 3.4" |
 sed -n  's/.*\([0-9][0-9]*[\ \t][0-9.]*[ \t]*$\)/\1/p'
2 3.4
116
iruvar

grep est le bon outil pour extraire.

en utilisant votre exemple et votre regex:

kent$  echo 'foo bar <foo> bla 1 2 3.4'|grep -o '[0-9][0-9]*[\ \t][0-9.]*[\ \t]*$'
2 3.4
60
Kent

Et pour encore une autre option, j'irais avec awk!

echo "foo bar <foo> bla 1 2 3.4" | awk '{ print $(NF-1), $NF; }'

Cela divisera l'entrée (j'utilise STDIN ici, mais votre entrée pourrait facilement être un fichier) sur des espaces, puis affichera le dernier champ, puis le dernier. Les variables $NF contiennent le nombre de champs trouvés après une explosion sur des espaces.

L'avantage de ceci est que peu importe si ce qui précède les deux derniers champs change, tant que vous ne voulez que les deux derniers champs, cela continue à fonctionner.

9
chooban

La commande de coupe est conçue pour cette situation exacte. Il "coupera" sur n'importe quel délimiteur et vous pourrez ensuite spécifier quels morceaux doivent être générés.

Par exemple: echo "foo bar <foo> bla 1 2 3.4" | cut -d " " -f 6-7

Entraînera la sortie de: 2 3.4

-d définit le délimiteur

-f sélectionne la plage de 'champs' à afficher. Dans ce cas, il s'agit du 6ème au 7ème morceau de la chaîne d'origine. Vous pouvez également spécifier la plage sous forme de liste, telle que 6,7.

3
carlin.scott