Como remover apenas a última barra no campo?

3

Eu tenho um arquivo json no qual preciso remover apenas as últimas barras. Veja o exemplo:

{"url":"http://example.com/vary/file/","originalUrl":"http://example.com/vary/file/","applications":[{.........}]}

Eu só quero que os dados sejam parecidos com:

{"url":"example.com/vary/file","originalUrl":"example.com/vary/file","applications":[{.........}]}

Como posso fazer isso com sed ?

    
por Jaffer Wilson 07.02.2017 / 11:02

3 respostas

6

Eu tomei a liberdade de modificar um pouco o input do OP, porque, como está, ele não está adequadamente estruturado json data (devido à {...} part) e implementou um pequeno script python que trabalha com vários dicionários, assumindo que nós está lidando com um dicionário por linha. Além disso, como foi discutido nos comentários à pergunta, o OP também queria remover http:// part.

O script abaixo implementa tudo o que foi discutido acima.

#!/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("")

Execução de teste:

$ 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"}
    
por Sergiy Kolodyazhnyy 08.02.2017 / 06:25
6

Se você insistir em usar sed , poderá combinar apenas a combinação /" , para remover o último / em cada campo, assumindo que não ocorrerá em algum lugar que você queira mantê-lo (o que deve ser bastante confiável neste caso)

$ sed 's|/"|"|g' file
{"url":"http://example.com/vary/file","originalUrl":"http://example.com/vary/file","applications":[{.........}]}

Eu usei | para delimitar em vez de / para salvar uma barra invertida. Você precisa de g para várias correspondências na mesma linha.

Aqui está uma maneira de retirar também o http:// na mesma chamada:

$ sed -r 's|"http://([^"]+)/"|""|g' url
{"url":"example.com/vary/file","originalUrl":"example.com/vary/file","applications":[{.........}]}

([^"]+) corresponderá a qualquer coisa entre "http:// e /" que não seja " . Nós salvamos esta parte com () e referência com .

    
por Zanna 07.02.2017 / 11:05
5

Um falecido:

uma opção de python simples e baseada em texto:

#!/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 apenas por diversão, outra maneira de dizer:

#!/usr/bin/env python3
import sys

[print(("").join(l.strip().replace("http://", "").rsplit("/", 1))) for l in open(sys.argv[1])]

fazendo a substituição / remoção da string ( http:// ) e a remoção da barra em aprox. 47 segundos em 14.000.000 de linhas, no meu antigo sistema.

Para usar:

python3 /path/to/script.py /path/to/inputfile > outputfile

Explicação

Como de costume, o Python é bastante legível, mas em detalhes:

  • rsplit("/", 1) divide a linha da direita (daí o r ) pelo delimitador / somente uma vez (daí o 1 )
  • l.replace("http://", "") substitui http:// por uma string vazia
  • ("").join() junta-se à lista, que foi criada por rsplit() novamente em uma linha
por Jacob Vlijm 08.02.2017 / 08:02