Créer une ligne en double basée sur le nombre maximal de délimiteurs dans un champ

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