Ajoutez des zéros de début jusqu'à ce que toutes les lignes avant la virgule soient composées de neuf caractères et insérez ensuite un caractère tous les trois numbers à l'aide de sed

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:

  1. 12345 doit devenir 000012345 et 12 devrait aboutir à 000000012 . En bref, l'accent est mis sur la séquence numérique avant la virgule.
  2. Le format des lignes est toujours 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.