J’ai un fichier qui contient plusieurs champs et 2 types de délimiteurs. Si le nombre de délimiteurs dans l’un des champs atteint un nombre défini, je souhaite diviser le champ après avoir rencontré le numéro sur la ligne suivante tout en répliquant la première partie de la ligne.
Est-ce possible dans awk ou sed?
Exemple
Consortingbution
a1 | b | c | d | 1,2,3,4 | a2 | b | c | d | 1,2,3,4,5,6,7,8,9,10 | a3 | b | c | d | 1,2 |
Nombre maximum = 6, à séparer par des virgules dans le champ 5
Sortie
a1 | b | c | d | 1,2,3,4 | a2 | b | c | d | 1,2,3,4,5,6 | a2 | b | c | d | 7,8,9,10 | a3 | b | c | d | 1,2 |
En supposant qu’il n’y ait pas plus d’un fractionnement:
$ sed -E 's/^(([^|]+\|){4})(([^,]+,){5}[^,]+),(.*)/\1\3|\n\1\5/' ip.txt a1|b|c|d|1,2,3,4| a2|b|c|d|1,2,3,4,5,6| a2|b|c|d|7,8,9,10| a3|b|c|d|1,2|
-E
utilise ERE, une version sed
utilise l’option -r
place ^(([^|]+\|){4})
4 premières colonnes délimitées par |
(([^,]+,){5}[^,]+)
6 colonnes délimitées par ,
(sans fin ,
) ,
virgule entre la 6ème et la 7ème colonne (.*)
rest de la ligne \1\3|\n\1\5
divisé selon les besoins La colonne et le nombre maximum peuvent également être transmis à partir des variables shell (exemple montré pour bash
)
$ col=5; max=6 $ sed -E "s/^(([^|]+\|){$((col-1))})(([^,]+,){$((max-1))}[^,]+),(.*)/\1\3|\n\1\5/" ip.txt a1|b|c|d|1,2,3,4| a2|b|c|d|1,2,3,4,5,6| a2|b|c|d|7,8,9,10| a3|b|c|d|1,2| $ col=5; max=8 $ sed -E "s/^(([^|]+\|){$((col-1))})(([^,]+,){$((max-1))}[^,]+),(.*)/\1\3|\n\1\5/" ip.txt a1|b|c|d|1,2,3,4| a2|b|c|d|1,2,3,4,5,6,7,8| a2|b|c|d|9,10| a3|b|c|d|1,2|
awk
à la rescousse!
awk -F\| -v OFS=\| -vc=',' ' {n=split($5,a,c); if(n>6) {f=$5; $5=a[1] ca[2] ca[3] ca[4] ca[5] ca[6]; print; $5=f; gsub(/([^,]+,){6}/,"",$5)}}1' file