
Eu tenho test.json
um arquivo com diferentes comprimentos de linhas. Algum exemplo fictício:
{ a: 123, b: sd, c: x45, d: 1, e: '' }
{ a: 5, b: bfgg, c: x4c, d: 31, e: '' }
Quero cortar toda a substring depois d
da parte e voltar apenas para cada linha:
{ a: 123, b: sd, c: x45 }
{ a: 5, b: bfgg, c: x4c }
eu encontreiaquiuma pergunta semelhante e tentei adaptar meu problema a ela:
echo test.json | sed 's/. d:/' > newtest.json
Preciso fazer isso para todo o arquivo, não apenas para uma linha.
Responder1
Se você está fazendo muito com a transformação do json na linha de comando, vale a pena investir seu tempo para obter a ferramenta jq e aprender a usá-la.
Embora as respostas acima mostrem que você pode fazer transformações mínimas sem realmente analisar o json, eventualmente você reinventará um analisador json com erros via regexp ou voltará a usar o analisador json nativo no idioma de sua escolha.
jq é rápido, simples de usar e uma ferramenta muito útil para ter em sua caixa de ferramentas.
BWT, seus dados de teste são json inválidos, o que complicará as soluções acima. Se você consertar isso
{ "a":123 , "b": "sd", "c": "x45", "d": 1, "e": "" }
{ "a":5 , "b": "bfgg", "c": "x4c", "d": 31, "e": "" }
Então este comando jq fará o que você quiser
jq -c '{a,b,c}' test.json
{"a":123,"b":"sd","c":"x45"}
{"a":5,"b":"bfgg","c":"x4c"}
Responder2
sed '/d:/s/, d:[^}]*/ /' test.json
ele percorrerá todo o arquivo e removerá em cada linha d:
todas , d:.*
as partes até }
o símbolo ( }
o símbolo permanecerá na linha).
Responder3
A resposta do @Rush usando sed
é provavelmente a melhor maneira de resolver isso, mas veja como você awk
também pode fazer isso:
$ awk -F ', d.* ' '{print $1, $2}' file.txt
{ a: 123, b: sd, c: x45 }
{ a: 5, b: bfgg, c: x4c }
O procedimento acima é usado awk
para dividir os dados em , d.*
. Isso produz 2 campos de dados $1
e $2
que contêm os dados resultantes da divisão das strings pelo AWK.
Responder4
Supondo que você tenha um arquivo JSON válido contendo um conjunto de objetos, como
{"a":123,"b":"sd","c":"x45","d":1,"e":"''"}
{"a":5,"b":"bfgg","c":"x4c","d":31,"e":"''"}
ou o equivalente
{
"a": 123,
"b": "sd",
"c": "x45",
"d": 1,
"e": "''"
}
{
"a": 5,
"b": "bfgg",
"c": "x4c",
"d": 31,
"e": "''"
}
e você gostaria de remover as chaves d
e e
de cada objeto.
Usando jq
, excluindo uma chave por vez:
jq -c 'del(.d) | del(.e)' file.json
Excluindo as duas chaves de uma vez:
jq -c 'del(.d, .e)' file.json
O resultado de qualquer um deles seria
{"a":123,"b":"sd","c":"x45"}
{"a":5,"b":"bfgg","c":"x4c"}
Uma terceira maneira de fazer isso, que não menciona as chaves reais por nome, seria converter os objetos em listas de "entradas" usando to_entries
, excluir as duas últimas entradas e converter a lista novamente em um objeto modificado:
jq -c 'to_entries | del(.[-2:]) | from_entries' file.json
É mais parecido com o que o texto da pergunta propõe e o resultado depende da ordem das chaves no objeto.