Mon fichier ressemble à ceci:
[581]((((((((501:0.00024264,451:0.00024264):0.000316197,310:0.000558837):0.00857295,((589:0.000409158,538:0.000409158):0.000658084,207:0.00106724
):0.00806454):0.0429702,(((198:0.00390205,91:0.00390205):0.016191,79:0.0200931):0.0147515,(187:0.00133008,50:0.00133008):0.0335145):0.0172574):0.
127506,((140:0.00253019,117:0.00253019):0.0533693,(((533:0.00728707,(463:8.80494e-05,450:8.80494e-05):0.00719902):0.0217722,389:0.0290593):0.0253
931,(((141:0.018004,107:0.018004):0.0143861,(111:0.00396127,(106:0.00161229,12:0.00161229):0.00234898):0.0284289):0.0145736,(129:0.0195982,((123:
0.0105973,66:0.0105973):0.0084867,10:0.019084):0.000514243):0.0273656):0.00748854):0.00144709):0.123708):0.000944439,((181:0.00108761,71:0.00108761):0.0819772);
[50]((((((((501:0.00024264,451:0.00024264):0.000316197,310:0.000558837):0.00857295,((589:0.000409158,538:0.000409158):0.000658084,207:0.00106724):0.00806454):0.0429702,(((198:0.00390205,91:0.00390205):0.016191,79:0.0200931):0.0147515,(187:0.00133008,50:0.00133008):0.0335145):0.0172574):0.127506,((140:0.00253019,117:0.00253019):0.0533693,(((533:0.00728707,(463:8.80494e-05,450:8.80494e-05):0.00719902):0.0217722,389:0.0290593):0.0253931,(((141:0.018004,107:0.018004):0.0143861,(111:0.00396127,(106:0.00161229,12:0.00161229):0.00234898):0.0284289):0.0145736,(129:0.0195982,((123:0.0105973,66:0.0105973):0.0084867,10:0.019084):0.000514243):0.0273656):0.00748854):0.00144709):0.123708):0.000944439,((181:0.00108761,71:0.00108761):0.0819772);
Chaque nouvelle ligne commence par le motif [number]
. Chaque ligne se termine par le motif );
.
Je dois extraire les nombres entre crochets à partir du début de chaque ligne et les écrire dans un nouveau fichier. Je ne sais pas combien de lignes le fichier a au préalable.
Vous pouvez y parvenir avec une seule commande grep
. Ceci est dû au fait que GNU grep vous permet d’utiliser une expression régulière Perl (-P
), qui prend en charge assertions de zone de largeur nulle (\K
et (?=
)
, dans ce cas):
grep -oP '^\[\K\d+(?=\])' infile
Comme écrit, cela enverra la sortie à votre terminal. Pour le rediriger vers un fichier, utilisez:
grep -oP '^\[\K\d+(?=\])' infile > outfile
Cette méthode a l'avantage de la brièveté et de la simplicité. Cela correspond au texte qui
est précédé de (\K
)
[
caractère (\[
) - \
est requis car [
a autrement une signification spéciale dans les expressions régulières^
);consiste en un ou plusieurs (+
) chiffres (\d
);
est suivi de ((?=
)
)
]
caractère (\]
) - comme avec [
, \
oblige ]
à correspondre de manière littérale.Utiliser sed
:
< inputfile sed -n 's/^\[\([0-9]*\)\].*$/\1/p' > out
Répartition des commandes :
< inputfile
: redirige le contenu de inputfile
vers stdin
-n
: supprime la sortie> out
: redirige le contenu de stdout
vers out
Répartition des regex :
s
: effectue une substitution/
: lance la regex^
: correspond au début de la ligne\[
: correspond à un caractère [
\(
: démarre le groupe de capture[0-9]*
: correspond à un nombre quelconque de chiffres\)
: arrête le groupe de capture\]
: correspond à un caractère ]
.*
: correspond à un nombre quelconque de caractères$
: correspond à la fin de la ligne/
: arrête la regex/démarre le remplacement\1
: remplace par le premier groupe de capture/
: arrête le remplacementp
: imprime uniquement les lignes correspondantesUtilisation de grep
+ tr
(si vous avez besoin d’une méthode fonctionnant à la fois sous Ubuntu et sur un autre système d’exploitation dont grep
ne prend pas en charge PCRE - sinon, reportez-vous à Eliah Kagan grep
- version seulement ):
< inputfile grep -o '^\[[0-9]*\]' | tr -d '[]' > out
Répartition des commandes :
< inputfile
dans grep
: redirige le contenu de inputfile
vers stdin
-o
in grep
: imprime uniquement la correspondance-d
dans tr
: supprime les caractères> out
dans tr
: redirige le contenu de stdout
vers out
Répartition des regex :
^
: correspond au début de la ligne\[
: correspond à un caractère [
[0-9]*
: correspond à un nombre quelconque de chiffres\]
: correspond à un caractère ]
la manière Perl
:
Perl -ne 'print "$1\n" if /^\[([0-9]*)\].*/' testdata > out
ou avec awk
:
awk 'match($0, /^\[[0-9]*\]/) {print substr($0, RSTART + 1, RLENGTH - 2)}' testdata > out
Regex utilisé dans les deux cas:
^\[[0-9]*\]
Explication
/^\[[0-9]*\]/
^
assert la position au début de la chaîne
\[
correspond au caractère [
littéralement
[0-9]*
correspond à un seul caractère présent dans la liste ci-dessous
Quantificateur: *
Entre zéro et un nombre illimité de fois, autant de fois que possible, redonner au besoin [gourmand]
0-9
un seul caractère compris entre 0 et 9
\]
correspond au caractère ]
littéralement
(source: debuggex.com )
Utilisez ceci dans Bash:
grep -oh '\[[0-9].*\]' mytestfile | sed 's/.*\[\([^]]*\)\].*/\1/g' > myresultfile
python
solution utilisant le module re
et considérant deux situations:
#!/usr/bin/env python2
import re
with open('/path/to/file.txt') as f:
for line in f:
digits_case_1 = re.search(r'(?<=^\[)\d+(?=\])', line)
digits_case_2 = re.search(r'(?<=^\[)\d+(?=\].*\);$)', line)
if digits_case_1:
print 'Not considering ");" at end: ' + digits_case_1.group()
if digits_case_2:
print 'Considering ");" at end: ' + digits_case_2.group()
Sortie:
Not considering ");" at end: 581
Not considering ");" at end: 50
Considering ");" at end: 50
Ici, j'ai considéré deux situations, car votre question ne me semble pas claire.
digits_case_1
imprimera la correspondance de chiffres entre []
au début de la ligne. Il ne sera pas tenu compte du fait que la ligne se termine par );
ou non.
digits_case_2
imprimera les chiffres entre []
au début de la ligne uniquement si celle-ci se termine par );
.
cat $FILE | awk -F\] '{ print $1 }' | grep '\[' | tr -d '['
Où la progression est:§
$ FILE=/tmp/tmp.tmp
$ cat $FILE
[581]((((((((501:0.00024264,451:0.00024264):0.000316197,310:0.000558837):0.00857295,((589:0.000409158,538:0.000409158):0.000658084,207:0.00106724
):0.00806454):0.0429702,(((198:0.00390205,91:0.00390205):0.016191,79:0.0200931):0.0147515,(187:0.00133008,50:0.00133008):0.0335145):0.0172574):0.
127506,((140:0.00253019,117:0.00253019):0.0533693,(((533:0.00728707,(463:8.80494e-05,450:8.80494e-05):0.00719902):0.0217722,389:0.0290593):0.0253
931,(((141:0.018004,107:0.018004):0.0143861,(111:0.00396127,(106:0.00161229,12:0.00161229):0.00234898):0.0284289):0.0145736,(129:0.0195982,((123:
0.0105973,66:0.0105973):0.0084867,10:0.019084):0.000514243):0.0273656):0.00748854):0.00144709):0.123708):0.000944439,((181:0.00108761,71:0.00108761):0.0819772);
[50]((((((((501:0.00024264,451:0.00024264):0.000316197,310:0.000558837):0.00857295,((589:0.000409158,538:0.000409158):0.000658084,207:0.00106724):0.00806454):0.0429702,(((198:0.00390205,91:0.00390205):0.016191,79:0.0200931):0.0147515,(187:0.00133008,50:0.00133008):0.0335145):0.0172574):0.127506,((140:0.00253019,117:0.00253019):0.0533693,(((533:0.00728707,(463:8.80494e-05,450:8.80494e-05):0.00719902):0.0217722,389:0.0290593):0.0253931,(((141:0.018004,107:0.018004):0.0143861,(111:0.00396127,(106:0.00161229,12:0.00161229):0.00234898):0.0284289):0.0145736,(129:0.0195982,((123:0.0105973,66:0.0105973):0.0084867,10:0.019084):0.000514243):0.0273656):0.00748854):0.00144709):0.123708):0.000944439,((181:0.00108761,71:0.00108761):0.0819772);
$ cat $FILE | awk -F\] '{ print $1 }'
[581
):0.00806454):0.0429702,(((198:0.00390205,91:0.00390205):0.016191,79:0.0200931):0.0147515,(187:0.00133008,50:0.00133008):0.0335145):0.0172574):0.
127506,((140:0.00253019,117:0.00253019):0.0533693,(((533:0.00728707,(463:8.80494e-05,450:8.80494e-05):0.00719902):0.0217722,389:0.0290593):0.0253
931,(((141:0.018004,107:0.018004):0.0143861,(111:0.00396127,(106:0.00161229,12:0.00161229):0.00234898):0.0284289):0.0145736,(129:0.0195982,((123:
0.0105973,66:0.0105973):0.0084867,10:0.019084):0.000514243):0.0273656):0.00748854):0.00144709):0.123708):0.000944439,((181:0.00108761,71:0.00108761):0.0819772);
[50
$ cat $FILE | awk -F\] '{ print $1 }' | grep '\['
[581
[50
$ cat $FILE | awk -F\] '{ print $1 }' | grep '\[' | tr -d '['
581
50
$
§ Pour ceux qui n'ont pas accès à la commande man
.