Si vous avez GNU grep, vous pouvez utiliser son -o
option pour rechercher une expression régulière et ne produire que la partie correspondante. (Les autres implémentations grep ne peuvent afficher que la ligne entière.) S'il y a plusieurs correspondances sur une ligne, elles sont imprimées sur des lignes distinctes.
grep -o '\[[0-9]*\]'
Si vous ne voulez que les chiffres et non les crochets, c'est un peu plus difficile; vous devez utiliser une assertion de largeur nulle: une expression rationnelle qui correspond à la chaîne vide, mais uniquement si elle est précédée ou suivie, selon le cas, d'un crochet. Les assertions de largeur nulle ne sont disponibles qu'en syntaxe Perl.
grep -P -o '(?<=\[)[0-9]*(?=\])'
Avec sed, vous devez désactiver l'impression avec -n
, faire correspondre la ligne entière et ne conserver que la partie correspondante. S'il y a plusieurs correspondances possibles sur une ligne, seule la dernière correspondance est imprimée. Voir Extraire une expression régulière correspondant à 'sed' sans imprimer les caractères environnants pour plus de détails sur l'utilisation de sed ici.
sed -n 's/^.*\(\[[0-9]*\]\).*/\1/p'
ou si vous ne voulez que les chiffres et non les crochets:
sed -n 's/^.*\[\([0-9]*\)\].*/\1/p'
Sans grep -o
, Perl est l'outil de choix ici si vous voulez quelque chose à la fois simple et compréhensible. Sur chaque ligne ( -n
), si la ligne contient une correspondance pour \[[0-9]*\]
, imprimez cette correspondance ( $&
) et une nouvelle ligne ( -l
).
perl -l -ne '/\[[0-9]*\]/ and print $&'
Si vous ne voulez que les chiffres, mettez des parenthèses dans l'expression régulière pour délimiter un groupe et imprimez uniquement ce groupe.
perl -l -ne '/\[([0-9]*)\]/ and print $1'
PS Si vous souhaitez uniquement exiger un ou plusieurs chiffres entre les crochets, changez [0-9]*
en [0-9][0-9]*
ou [0-9]+
en Perl.
[number]
" signifie sauf[0-9]
perl
affirmations regex semblent vraiment utiles! J'ai lu à leur sujet après vous avoir vu utiliser des assertions en arrière et en avant, même dans grep (j'avais désactivé le fait que vous puissiez choisir un moteur d'expression régulière). Je vais consacrer un peu plus de temps à l'expression rationnelle de Perl à partir d'ici. Merci ... PS .. Je viens de lireman grep
... "C'est très expérimental et grep -P peut avertir de fonctionnalités non implémentées." ... J'espère que cela ne signifie pas instable (?) ...Vous ne pouvez pas le faire avec
cut
.tr -c -d '0123456789\012'
sed 's/[^0-9]*//g'
awk -F'[^0-9]+' '{ print $1$2$3 }'
grep -o -E '[0-9]+'
tr
est le plus naturel pour le problème et fonctionnerait probablement le plus rapidement, mais je pense que vous auriez besoin d'entrées gigantesques pour séparer l'une de ces options en termes de vitesse.la source
^.*
est gourmand et consomme tout sauf le dernier chiffre, et+
doit être\+
ou bien utiliser le posix\([0-9][0-9]*\)
.... et en tout cas's/[^0-9]*//g'
fonctionne aussi bien,... Thanks for the
par exemple tr -c`, mais n'est-ce pas\012
superflu?\012
: il est nécessaire sinontr
mangera les nouvelles lignes.\0
,1
,2
(ou même \, 0, 1, 2). Je ne suis pas assez en phase avec l'octal semble-t-il .. Merci.Si vous voulez dire extraire un ensemble de chiffres consécutifs entre des caractères non numériques, je suppose
sed
que ceawk
sont les meilleurs (bien qu'ilgrep
soit également en mesure de vous donner les caractères correspondants):sed
: vous pouvez bien sûr faire correspondre les chiffres, mais il est peut-être intéressant de faire le contraire, supprimez les non-chiffres (fonctionne dans la mesure où il n'y a qu'un seul numéro par ligne):grep
: vous pouvez faire correspondre des chiffres consécutifsJe ne donne pas d'exemple
awk
car je n'en ai aucune expérience; il est intéressant de noter que, bien qu'il s'agisse d'sed
un couteau suisse,grep
vous offre un moyen plus simple et plus lisible de le faire, qui fonctionne également pour plus d'un numéro sur chaque ligne d'entrée (le-o
seul imprime les parties correspondantes de l'entrée, chacune sur sa propre ligne):la source
sed
eqivalent du « plus d'un numéro par ligne » par exemplegrep -o '[[:digit:]]*'
. . .sed -nr '/[0-9]/{ s/^[^[0-9]*|[^0-9]*$//g; s/[^0-9]+/\n/g; p}'
... (+1)Puisqu'il a été dit que cela ne pouvait pas être fait
cut
, je montrerai qu'il est facilement possible de produire une solution qui n'est au moins pas pire que certaines des autres, même si je n'approuve pas l'utilisation decut
comme la "meilleure" (ou même une solution particulièrement bonne). Il convient de dire que toute solution ne recherchant pas spécifiquement les chiffres*[
et]*
autour d'eux fait des hypothèses simplificatrices et est donc sujette à l'échec sur des exemples plus complexes que ceux fournis par le demandeur (par exemple, les chiffres à l'extérieur*[
et]*
, qui ne doivent pas être affichés). Cette solution vérifie au moins les parenthèses, et elle pourrait être étendue pour vérifier également les astérisques (laissés en exercice au lecteur):Cela utilise l'
-d
option, qui spécifie un délimiteur. De toute évidence, vous pouvez également diriger l'cut
expression au lieu de lire un fichier. Bien que cecut
soit probablement assez rapide, car il est simple (pas de moteur d'expression régulière), vous devez l'invoquer au moins deux fois (ou encore un peu de temps pour vérifier*
), ce qui crée une surcharge de processus. Le seul réel avantage de cette solution est qu'elle est plutôt lisible, en particulier pour les utilisateurs occasionnels peu familiarisés avec les constructions d'expression régulière.la source