J'ai un fichier qui ressemble à ceci:

 [                                 
{                                 
     "ncyc" :  28817,         
    "icels" :    128,         
    "jcels" :    128,         
        "t" :   0.185896E-006,
       "dt" :   0.955602E-012,
   "dtcour" :   0.100000E+021,
      "dti" :   0.100000E+021,
      "dtc" :   0.262902E-011,
    "dtvol" :   0.239735E-010,
   "dthall" :   0.100000E+021,
  "dtlaser" :  -0.925596E+062,
    "dtmax" :   0.200000E-009,   
}
]

Je souhaite supprimer la dernière virgule de ce fichier. Il apparaît à la 14e ligne à la position 34. Je pourrais le faire manuellement s'il s'agissait d'un fichier, mais je dois le faire pour 300 fichiers

-1
wander95 24 janv. 2017 à 21:32

4 réponses

Meilleure réponse

Merci pour les réponses. J'ai pu facilement résoudre la question moi-même en utilisant Python:

  f=open(fjson, 'r')
  data= f.readlines()
  ndx=len(data)
  data[ndx-3]= data[ndx-3].replace(',', '')
0
wander95 24 janv. 2017 à 20:09

Selon la plate-forme, sed ou awk peuvent avoir des résultats différents, perl peut être plus flexible:

perl -i.bak -00pe 's/,(?!.*,)//s' file
# , matches a comma.
# (?!.*,) negative lookahead asserts no comma after matched comma. 
# s is a DOTALL modifier matching newline characters also.
1
l'L'l 24 janv. 2017 à 19:10

Ceci est un simple one-liner ed:

ed foo.json <<EOF
?,?s/,\([^,]*\)$/\1/
wq
EOF

Cette ligne peut être divisée en une adresse et une commande.

L'adresse est ?,?, à savoir la ligne précédente correspondant à l'expression régulière ,.

La commande est s/re/replacement/, où l'expression régulière est ,\([^,]*\)$ (un littéral ,, un groupe capturé de zéro caractère ou plus qui ne sont pas ,, et la fin du line), et le remplacement est \1 (le premier groupe capturé).

Techniquement, c'est un script ed sur deux lignes, wq pour enregistrer et quitter.

Vous pouvez l'invoquer dans une boucle avec find, par exemple:

find . -name '*.json' | while read name ; do
ed -s $name <<EOF
H
[…ed commands…]
wq
EOF
done

J'ai également ajouté ed -s pour supprimer le message de taille de fichier, et H pour générer des erreurs détaillées au lieu de l'infâme ?.

1
Josh Lee 24 janv. 2017 à 19:57

Sed est votre ami:

sed -i.bak '14s/,[[:blank:]]*$//' file ...

C'est un peu fragile: on suppose que la ligne à supprimer est toujours la 14e, pas nécessairement la ligne avant l'accolade de fermeture.

1
glenn jackman 24 janv. 2017 à 18:58