J'ai donc une ligne:
ID: 54376
Pouvez-vous m'aider à créer une expression régulière qui ne renverrait que des chiffres sans "ID:"?
REMARQUE: cette chaîne se trouve dans un fichier.
J'ai donc une ligne:
ID: 54376
Pouvez-vous m'aider à créer une expression régulière qui ne renverrait que des chiffres sans "ID:"?
REMARQUE: cette chaîne se trouve dans un fichier.
Réponses:
Essaye ça:
grep -oP '(?<=ID: )[0-9]+' file
ou:
perl -nle 'print $1 if /ID:.*?(\d+)/' file
-o
et -P
sont des extensions GNU pour grep
. -o
fonctionne également sur les BSD. La prise en charge de PCRE avec -P
n'est pas toujours compilée non plus.
Utilisez egrep
avec -o
ou grep
avec l' -Eo
option pour obtenir uniquement le segment correspondant. Utilisez [0-9]
comme expression régulière pour obtenir uniquement des nombres:
grep -Eo [0-9]+ filename
Il y a plusieurs façons de procéder. Par exemple:
Utilisez GNU grep
avec des PCRE récents et faites correspondre les nombres après ID:
:
grep -oP 'ID:\s*\K\d+' file
Utilisez awk
et imprimez simplement le dernier champ de toutes les lignes commençant parID:
awk '/^ID:/{print $NF}' file
Cela imprimera également les champs qui ne sont pas des nombres, pour obtenir des nombres uniquement et uniquement dans le deuxième champ, utilisez
awk '($1=="ID:" && $2~/^[0-9]+$/){print $2}' file
Utilisez GNU grep avec les expressions régulières étendues et analysez-le deux fois:
grep -Eo '^ID: *[0-9]+' file | grep -o '[0-9]*'
\K
fait-on dans le premier exemple?
-o
de n'imprimer que la partie correspondante mais aussi de jeter les choses qui ne m'intéressent pas. Comparer echo "foobar" | grep -oP "foobar"
etecho "foobar" | grep -oP 'foo\Kbar'
sed -n '/ID: 54376/,${s/[^ 0-9]*//g;/./p}'
Cela n'imprimera que tous les nombres et espaces survenant après ID: 54376
dans n'importe quelle entrée de fichier.
Je viens de mettre à jour ce qui précède un peu pour le rendre un peu plus rapide avec *
et pour ne pas p
imprimer de lignes vides après avoir supprimé les caractères non {numériques, espace}.
Il aborde des lignes de regex à /ID: 54376/
,
travers la $
dernière et les s///
supprime tous ou les *
caractères ^
ne [^ 0-9]*
puis p
rints /
une /
ligne avec un .
caractère restant.
{
echo line
printf 'ID: 54376\nno_nums_or_spaces\n'
printf '%s @nd 0th3r char@cter$ %s\n' $(seq 10)
echo 'ID: 54376'
} | sed -n '/ID 54376/,${s/[^ 0-9]*//g;/./p}'
54376
1 03 2
3 03 4
5 03 6
7 03 8
9 03 10
54376
Utilisation de sed:
{
echo "ID: 1"
echo "Line doesn't start with ID: "
echo "ID: Non-numbers"
echo "ID: 4"
} | sed -n '/^ID: [0-9][0-9]*$/s/ID: //p'
La valeur -n
"n'imprime rien par défaut", la valeur /^ID: [0-9][0-9]*$/
"pour les lignes correspondant à cette expression régulière" (commence par "ID:", puis 1 ou plusieurs chiffres, puis la fin de la ligne), et s/ID: //p
la forme est s/pattern/repl/flags
- s
signifie que nous fais un substitut, pour remplacer le motif "ID: "
par du texte de remplacement ""
(chaîne vide) en utilisant le p
drapeau, ce qui signifie "imprimer cette ligne après avoir fait la substitution".
Production:
1
4
Une autre commande GNU sed,
sed -nr '/ID: [0-9]+/ s/.*ID: +([0-9]+).*/\1/p' file
Il imprime n'importe quel nombre après ID:
+
. Si la différence entre un caractère et 3 caractères est votre script ne fonctionne pas dans tous les sed
s vous devriez probablement faire: sed -n '/ID: \([0-9][0-9]*\).*/{s//\1/;s/.*[^0-9]//;/./p}'
. Votre réponse manque également la première ID: [0-9]
d'une ligne contenant deux occurrences de ID: [0-9]
.
Utilisez grep + awk:
grep "^ID" your_file | awk {'print $2'}
Bonus: facile à lire :)
grep
si vous utilisez awk
. awk '/^ID/ { print $2 }'
fait la même chose et évite les problèmes de mise en mémoire tampon des lignes grep . C'est aussi à peu près la même chose que l'une des solutions dans la réponse de @ terdon.