Le but est d'append des zéros avant que la virgule ne comprenne neuf caractères, puis d'insert un caractère tous les trois numbers en utilisant sed
.
Consortingbution
12345,1s4c3v6s3nh6 123456789,9h5vgbdx34dc 12,7h4f45dcvbgh 1234567,09klijnmh563
Résultat actuel
[vagrant@localhost ~]$ sed -e 's/\([0-9]\{3\}\),/\/\1\//g' file 12/345/1s4c3v6s3nh6 123456/789/9h5vgbdx34dc 12,7h4f45dcvbgh 1234/567/09klijnmh563
Résultat attendu
000/012/345,1s4c3v6s3nh6 123/456/789,9h5vgbdx34dc 000/000/012,7h4f45dcvbgh 001/234/567,09klijnmh563
Remarque:
12345
doit devenir 000012345
et 12
devrait aboutir à 000000012
. En bref, l'accent est mis sur la séquence numérique avant la virgule. MAX_9_characters,fixed_12_characters
. Par exemple, 1234512345,1s4c3v6s3nh6
ne résidera jamais dans le file d'input. Le problème est que le nombre de caractères n'a pas pu être égalisé en utilisant sed. Comment cela pourrait-il être accompli?
Si votre input n'a pas de numéro de séquence long dans le second champ, essayez:
$ sed -e 's|^[^,]*|#000000000&|;s|#[^,]*\(.\{9\}\),|\1,|;s|\([0-9]\{3\}\)|\1/|g;s|/\([^0-9]\)|\1|;s|/$||' file 000/012/345,1s4c3v6s3nh6 123/456/789,9h5vgbdx34dc 000/000/012,7h4f45dcvbgh 001/234/567,09klijnmh563
Explication
s|^[^,]*|#000000000&|
: on associe tout du début à la première ,
on le remplace par un fabricant #
et n numbers 0, où n est la longueur que l'on veut compresser.
s|#[^,]*\(.\{9\}\),|\1,|
: nous faisons correspondre toutes les choses du marqueur au premier ,
gardons seulement les 9 derniers caractères avant, rejetons le rest.
s|\([0-9]\{3\}\)|\1/|g
: ajoutez une /
chaque 3 séquence de numbers.
s|/\([^0-9]\)|\1|;s|/$||
: si après /
n'est pas un nombre ou /
est à la fin de la ligne, nous l'enlevons.
ou plus facile avec perl
:
$ perl -F',' -anle ' $F[0] = sprintf "%09s", $F[0]; $F[0] =~ s|.{3}|$&/|g; chop $F[0]; print join ",",@F; ' file 000/012/345,1s4c3v6s3nh6 123/456/789,9h5vgbdx34dc 000/000/012,7h4f45dcvbgh 001/234/567,09klijnmh563
Cela peut probablement être fait dans sed
mais c'est au-delà de mon sed-fu. Voici une solution différente:
perl -F, -lane '$F[0]=sprintf("%09s",$F[0]); $F[0]=~s#(...)(?!$)#$1/#g; print "$F[0],$F[1]"' file
Le -a
divise chaque ligne d'input en champs et l'enregistre dans le tableau @F
. Le -F
définit le délimiteur de champ ( ,
ici). Le -l
supprime les returns à la ligne de fin et ajoute une nouvelle ligne à la fin de chaque appel d' print
et le n
provoque la lecture du file d'input ligne par ligne et le script donné par -e
appliqué à chaque ligne.
Le script lui-même fait 3 choses. Tout d'abord, il utilise sprintf
pour append le premier 0
au premier champ ( $F[0]
). Ensuite, il remplace tous les sets de trois caractères dans le 1er champ (sauf ceux à la fin: (?!$
) ) with themselves followed by a
/ `. Enfin, il imprime le 1er champ maintenant modifié, une virgule et le 2ème champ.
Maintenant que la question a été affinée, nous pouvons simplifier la réponse de Gnouc
sed 's|^|000000000|;s|.*\(...\)\(...\)\(...,\)|\1/\2/\3|' file
ou, si vous voulez conserver une bouffée d'une solution générale,
sed 's|^|000000000|;s|.*\(.\{3\}\)\(.\{3\}\)\(.\{3\},\)|\1/\2/\3|' file
Ceux-ci, comme au less certaines des autres réponses, supposent qu'il n'y a qu'une seule virgule sur chaque ligne.