¿Comando para eliminar una parte de los datos JSON de cada línea?

¿Comando para eliminar una parte de los datos JSON de cada línea?

Tengo test.jsonun archivo con diferentes longitudes de filas. Algún ejemplo ficticio:

{ a: 123, b: sd, c: x45, d: 1, e: '' }
{ a: 5, b: bfgg, c: x4c, d: 31, e: '' }

Quiero cortar toda la subcadena después de dla parte y recuperar solo cada línea:

{ a: 123, b: sd, c: x45 }
{ a: 5, b: bfgg, c: x4c }

encontréaquíuna pregunta similar y traté de adaptar mi problema a ella:

echo test.json |  sed 's/. d:/' > newtest.json

Necesito hacerlo para todo el archivo, no solo para una línea.

Respuesta1

Si está haciendo mucho para transformar json en la línea de comando, vale la pena dedicar tiempo a obtener la herramienta jq y aprender a usarla.

http://stedolan.github.io/jq/

Si bien las respuestas anteriores muestran que puede realizar transformaciones mínimas sin analizar el json, eventualmente reinventará un analizador json con errores a través de expresiones regulares o volverá a usar el analizador json nativo en el idioma que elija.

jq es rápido, fácil de usar y una herramienta muy útil para tener en su caja de herramientas.

BWT, sus datos de prueba no son json válidos, lo que complicará las soluciones anteriores. Si lo arreglas

{ "a":123 , "b": "sd", "c": "x45", "d": 1, "e": "" }
{ "a":5 , "b": "bfgg", "c": "x4c", "d": 31, "e": "" }

Entonces este comando jq hará lo que quieras

 jq -c '{a,b,c}' test.json

{"a":123,"b":"sd","c":"x45"}
{"a":5,"b":"bfgg","c":"x4c"}

Respuesta2

sed '/d:/s/, d:[^}]*/ /' test.json

recorrerá todo el archivo y eliminará cada línea con d:todas , d:.*las partes hasta }el símbolo ( }el símbolo permanecerá en la línea).

Respuesta3

La respuesta de @Rush sedes probablemente la mejor manera de resolver esto, pero así es como puedes hacerlo awktambién:

$ awk -F ', d.* ' '{print $1, $2}' file.txt 
{ a: 123, b: sd, c: x45 }
{ a: 5, b: bfgg, c: x4c }

Lo anterior se utiliza awkpara dividir los datos , d.*. Esto produce 2 campos de datos $1que $2contienen los datos resultantes de la división de las cadenas por parte de AWK.

Respuesta4

Suponiendo que tiene un archivo JSON válido que contiene un conjunto de objetos, como

{"a":123,"b":"sd","c":"x45","d":1,"e":"''"}
{"a":5,"b":"bfgg","c":"x4c","d":31,"e":"''"}

o el equivalente

{
  "a": 123,
  "b": "sd",
  "c": "x45",
  "d": 1,
  "e": "''"
}
{
  "a": 5,
  "b": "bfgg",
  "c": "x4c",
  "d": 31,
  "e": "''"
}

y le gustaría eliminar las claves dy ede cada objeto.

Usando jq, eliminando una clave a la vez:

jq -c 'del(.d) | del(.e)' file.json

Eliminar ambas claves a la vez:

jq -c 'del(.d, .e)' file.json

El resultado de cualquiera de estos sería

{"a":123,"b":"sd","c":"x45"}
{"a":5,"b":"bfgg","c":"x4c"}

Una tercera forma de hacer esto, que no menciona las claves reales por nombre, sería convertir los objetos en listas de "entradas" usando to_entries, luego eliminar las dos últimas entradas y convertir la lista nuevamente en un objeto modificado:

jq -c 'to_entries | del(.[-2:]) | from_entries' file.json

Esto se parece más a lo que propone el texto de la pregunta y el resultado depende del orden de las claves en el objeto.

información relacionada