
Tengo test.json
un 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 d
la 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.
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 sed
es probablemente la mejor manera de resolver esto, pero así es como puedes hacerlo awk
tambié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 awk
para dividir los datos , d.*
. Esto produce 2 campos de datos $1
que $2
contienen 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 d
y e
de 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.