J'ai un fichier JSON où je dois supprimer les dernières barres obliques uniquement. Voir l'exemple:
{"url":"http://example.com/vary/file/","originalUrl":"http://example.com/vary/file/","applications":[{.........}]}
Je veux juste que les données ressemblent à:
{"url":"example.com/vary/file","originalUrl":"example.com/vary/file","applications":[{.........}]}
Comment puis-je faire cela avec sed
?
J'ai pris la liberté de modifier légèrement l'entrée d'OP, car, dans l'état actuel des choses, les données json
ne sont pas correctement structurées (en raison de la partie {...}
) et j'ai implémenté un petit script python qui fonctionne. avec plusieurs dictionnaires, en supposant que nous avons affaire à un dictionnaire par ligne. De plus, comme cela a été discuté dans les commentaires sur la question, OP souhaitait également supprimer la partie http://
.
Le script ci-dessous implémente tout ce qui a été discuté ci-dessus.
#!/usr/bin/env python
import json,sys
with open(sys.argv[1]) as f:
for line in f:
data=json.loads(line)
if data["url"][-1] == '/':
data["url"]=data["url"][:-1].replace('http://','')
if data["originalUrl"][-1] == '/':
data["originalUrl"]=data["originalUrl"][:-1].replace('http://','')
json.dump(data,sys.stdout)
print("")
Essai:
$ cat input.txt
{"url":"http://example.com/vary/file/","originalUrl":"http://example.com/vary/file/","applications":[{"somedata": "blah"}]}
{"url":"http://another-example.com/vary/file/","originalUrl":"http://example.com/vary/file/","applications":[{"somedata": "blah"}]}
$ ./remove_slash.py input.txt
{"url": "example.com/vary/file", "applications": [{"somedata": "blah"}], "originalUrl": "example.com/vary/file"}
{"url": "another-example.com/vary/file", "applications": [{"somedata": "blah"}], "originalUrl": "example.com/vary/file"}
Si vous insistez pour utiliser sed
, vous pouvez simplement associer la combinaison /"
, pour supprimer le dernier /
de chaque champ, en supposant que cela ne se produira pas à un endroit où vous souhaitez le conserver être assez fiable dans ce cas)
$ sed 's|/"|"|g' file
{"url":"http://example.com/vary/file","originalUrl":"http://example.com/vary/file","applications":[{.........}]}
J'ai utilisé |
pour délimiter au lieu de /
pour enregistrer une barre oblique inversée. Vous avez besoin de g
pour plusieurs correspondances sur la même ligne.
Voici un moyen de sortir le http://
également dans le même appel:
$ sed -r 's|"http://([^"]+)/"|"\1"|g' url
{"url":"example.com/vary/file","originalUrl":"example.com/vary/file","applications":[{.........}]}
([^"]+)
correspond à tout ce qui se situe entre "http://
et /"
qui n'est pas un "
. Nous sauvegardons cette partie avec ()
et nous référons avec \1
.
Un retard:
une simple option python basée sur du texte:
#!/usr/bin/env python3
import sys
with open(sys.argv[1]) as data:
for l in data:
print(("").join(l.strip().replace("http://", "").rsplit("/", 1)))
Ou, juste pour le plaisir, une autre façon de le dire:
#!/usr/bin/env python3
import sys
[print(("").join(l.strip().replace("http://", "").rsplit("/", 1))) for l in open(sys.argv[1])]
effectuer à la fois le remplacement/retrait de la chaîne (http://
) et la suppression de la barre oblique dans env. 47 secondes sur 14.000.000 millions de lignes, sur mon ancien système.
Utiliser:
python3 /path/to/script.py /path/to/inputfile > outputfile
Comme d'habitude, python est assez lisible, mais en détail:
rsplit("/", 1)
divise la ligne de droite (d'où le r
) par le délimiteur /
ne seule fois (d'où le 1
)l.replace("http://", "")
remplace http://
par une chaîne vide("").join()
rejoint la liste créée à nouveau par rsplit()
dans une ligne