web-dev-qa-db-fra.com

Comment supprimer uniquement la dernière barre oblique du champ?

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?

3
Jaffer Wilson

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"}
6
Sergiy Kolodyazhnyy

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.

6
Zanna

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

Explication

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
5
Jacob Vlijm