Chaîne d'entrée:

1234 5678 9101 1234
2999 5178 9101 2234
9999 5628 9201 1232
8888 3678 9101 1232

La chaîne d'entrée ci-dessus comporte des espaces après la 1ère , 2ème et 3ème ligne. Chaque ligne après le dernier chiffre a des espaces, puis la nouvelle ligne commence à l'exception de la dernière ligne.

La dernière ligne se termine au dernier caractère (chiffre «2») et n'a rien d'autre après cela.

Correspondance obligatoire : je souhaite faire correspondre uniquement les trois premiers blocs de chiffres de chaque ligne (la correspondance ne doit pas inclure l'espace unique entre les blocs).

Résultat attendu avec sed :

**** **** **** 1234 **** **** **** 2234 **** **** **** 1232 **** **** **** 1232

Mon approche : j'utilise une recherche négative (je sais que sed ne prend pas en charge les assertions de recherche) \d{4}(?! {2,}) qui correspond, dans les trois premières lignes, uniquement aux trois premiers blocs de chiffres, mais à la quatrième ligne correspond à tous les blocs de chiffres (évidemment, car la dernière ligne n'a pas 2 espaces après le dernier chiffre.)

Violon: https://regex101.com/r/VzQf3D/2

-1
HarshvardhanSharma 30 déc. 2017 à 12:33

6 réponses

Meilleure réponse

Avec Perl, je dirais:

perl -pe 's/(\d{4})(?= [^ ])/****/g' file
2
tshiono 30 déc. 2017 à 14:45

Si je comprends bien, tu peux essayer

sed ':A;s/\(.*\)\([^ |\*]\)\([ |\*]*[ ][^ ][^ ]*[ ]*$\)/\1*\3/;tA' infile
1
ctac_ 30 déc. 2017 à 11:12

Avec GNU sed:

sed -E 'h;s/^(([^ ]+ ){3})//;x;s/[^ ]*$//;s/[0-9]/*/g;G;s/\n//' file

Production:

**** **** **** 1234
**** **** **** 2234
**** **** **** 1232
**** **** **** 1232

Voir: man sed

1
Cyrus 30 déc. 2017 à 13:10

Je ne suis pas sûr de bash, mais pour une expression régulière normale, j'utiliserais

^(?: *)(\d{4})(?: +)(\d{4})(?: +)(\d{4})  # with multiline flag

Explication:

^ is line start 
(?: *) is a non capturing group of any number of spaces
(\d{4}) is a capturing group of 4 digit
(?: +) is a non capturing group of one or more number of spaces
(\d{4}) is a capturing group of 4 digit
(?: +) is a non capturing group of one or more number of spaces
(\d{4}) is a capturing group of 4 digit

Violon: https://regexr.com/3ike0


Si vous utilisez sed pour cette expression régulière, les groupes non capturants ne sont pas une possibilité selon

comment spécifiez-vous les groupes non capturants dans sed?

Réponse par https://stackoverflow.com/a/36546377/7505395 ainsi que d'autres fournis pour cette question. Désolé.

0
Patrick Artner 30 déc. 2017 à 13:09

Puisque vous ne nous avez pas montré la sortie attendue, mettez cette solution uniquement selon votre explication. Je crois que vous avez besoin des 3 premières colonnes dans chaque ligne de votre Input_file si oui, alors ce qui suit peut vous aider. Si vos besoins sont différents, veuillez nous montrer le résultat attendu avec quelques détails supplémentaires dans les balises de code dans votre message.

awk '{print $1,$2,$3}'  Input_file

La sortie sera la suivante.

1234 5678 9101
2999 5178 9101
9999 5628 9201
8888 3678 9101

EDIT: Vu votre message modifié, au cas où vous n'avez pas besoin d'espace entre 3 colonnes dans la sortie, ce qui suit peut vous aider.

awk '{print $1 $2 $3}' Input_file
0
RavinderSingh13 30 déc. 2017 à 09:49

Qu'en est-il de

^(?:(?:^| +)[0-9]{4})(?=[0-9]{4} $)
0
iBug 30 déc. 2017 à 10:46