web-dev-qa-db-fra.com

N'a pas besoin de toute la ligne, juste le match de l'expression régulière

J'ai simplement besoin d'obtenir le match d'une expression régulière:

$ cat myfile.txt | SOMETHING_HERE "/(\w).+/"

La sortie ne doit être que ce qui a été adapté, à l'intérieur de la parenthèse.

Ne pense pas que je puisse utiliser grep car il correspond à toute la ligne.

S'il vous plait, faites moi savoir comment faire ça.

15
Alex L

Utilisez le -o option dans grep.

Par exemple:

$ echo "foobarbaz" | grep -o 'b[aeiou]r'
bar
18
Rory
    sed -n "s/^.*\(captureThis\).*$/\1/p"

-n      don't print lines
s       substitute
^.*     matches anything before the captureThis 
\( \)   capture everything between and assign it to \1 
.*$     matches anything after the captureThis 
\1      replace everything with captureThis 
p       print it
6
Joshua

Si vous ne voulez que ce qui est entre la parenthèse, vous avez besoin de quelque chose qui prend en charge la capture de sous-matchs (groupes de capture nommés ou numérotés). Je ne pense pas que Grep ou Egrep puisse faire cela, Perl et SED peuvent. Par exemple, avec Perl:

Si un fichier appelé FOO a une ligne en cela est comme suit:

/adsdds      /

Et vous faites:

Perl -nle 'print $1 if /\/(\w).+\//' foo

La lettre A est renvoyée. Ce n'est peut-être pas ce que vous voulez. Si vous nous dites ce que vous essayez de faire correspondre, vous pourriez avoir une meilleure aide. 1 $ est ce qui a été capturé dans la première série de parenthèses. 2 $ serait le deuxième ensemble, etc.

4
Kyle Brandt

Parce que vous avez étiqueté votre question comme Bash En plus de Shell, il y a une autre solution à côté GREP:

Bash a son propre moteur d'expression régulier depuis la version 3.0, en utilisant le =~ Opérateur, comme Perl.

maintenant, étant donné le code suivant:

#!/bin/bash
DATA="test <Lane>8</Lane>"

if [[ "$DATA" =~ \<Lane\>([[:digit:]]+)\<\/Lane\> ]]; then
        echo $BASH_REMATCH
        echo ${BASH_REMATCH[1]}
fi
  • Notez que vous devez l'invoquer comme bash et pas seulement sh afin d'obtenir toutes les extensions
  • $BASH_REMATCH donnera la chaîne entière comme appariée par toute l'expression régulière, alors <Lane>8</Lane>
  • ${BASH_REMATCH[1]} donnera la pièce assortie par le 1er groupe, donc seulement 8
4
DrYak

En supposant que le fichier contient:

$ cat file
Text-here>xyz</more text

Et vous voulez le (s) caractère (s) entre > Et </, Vous pouvez utiliser:

grepgrep -oP '.*\K(?<=>)\w+(?=<\/)' file
[.____] SEDsed -nE 's:^.*>(\w+)</.*$:\1:p' file
[.____] awkawk '{print(gensub("^.*>(\\w+)</.*$","\\1","g"))}' file
[.____] PerlPerl -nle 'print $1 if />(\w+)<\//' file

Tous imprimeront une chaîne "xyz".

Si vous voulez capturer les chiffres de cette ligne:

$ cat file
Text-<here>1234</text>-ends

grepgrep -oP '.*\K(?<=>)[0-9]+(?=<\/)' file
[.____] SEDsed -E 's:^.*>([0-9]+)</.*$:\1:' file
[.____] awkawk '{print(gensub(".*>([0-9]+)</.*","\\1","g"))}' file
[.____] PerlPerl -nle 'print $1 if />([0-9]+)<\//' file

2
Arrow