удалите повторяющиеся представления 1:M в файлах JSON

#json #bash

Вопрос:

У меня около 700 файлов JSON с повторяющимися уязвимостями, такими как:

 {
  "vulnerabilities": [
}
{
  "vulnerabilities": [
}
 

Это представление json показывает наличие уязвимостей. Я хочу удалить все после первого появления уязвимостей {} для каждого файла. Поэтому я хочу, чтобы каждый json затем сохранялся с этим представлением:

 {
  "vulnerabilities": [
}
 

У меня есть петля:

 for file in *.json; do
# logic
done
 

это просматривает все файлы json в настоящее время и делает с ними логику.

Как я могу добиться удаления всего в каждом файле json после первого появления vulnerabilities { }

Комментарии:

1. ты знаешь jq ?

2. Вывод, который вы говорите, что хотите, вообще не является допустимым JSON. (Как и тот вклад, который, как вы утверждаете, у вас есть).

Ответ №1:

Если у вас есть допустимый JSON, такой как:

 [
  {
    "vulnerabilities": [ {"issue":"root access"}, {"timestamp":"2021-04-19T20:27:23 00:00"} ]
  },
  {
    "vulnerabilities": [ {"issue":"something else"}, {"timestamp":"2021-04-18:27:23 00:00"}]
  }
]
 

и у вас есть jq в вашей системе, то это просто, как:

 jq '.[0]' vulnerabilities.json
 

получить:

 {
  "vulnerabilities": [
    {
      "issue": "root access"
    },
    {
      "timestamp": "2021-04-19T20:27:23 00:00"
    }
  ]
}
 

Комментарии:

1. Также вероятно, что вводом операции может быть поток объектов JSON, а не один документ. jq тоже может справиться с этим, но они не сказали нам, каков их формат, с достаточной конкретикой, чтобы знать.

2.@stdunbar — нет, у меня есть дубликаты, такие как: выше, используя { }

Ответ №2:

Это приведет к удалению всех строк после }:

 for file in *.json; do
  sed '/}/q' $file > $file.new
done
 

sed завершит работу после поиска и печати первого } .

Каждый сокращенный файл сохраняется в файле $file.new.

Например,

 cat f2.json
 
 {
  "vulnerabilities": ["f2",1],
  "happiness": ["good thing", 10] }
{
  "vulnerabilities": ["f2",2]
}
{
  "vulnerabilities": ["f2",3] }
 

появится файл f2.json.new

 {
  "vulnerabilities": ["f2",1],
  "happiness": ["good thing", 10] }
 

Если у вас более сложный файл json, мы можем использовать команду awk:

 for file in *.json; do
  awk 'BEGIN { nopen = 0; nclose = 0; } { nopen  = gsub(/{/, "{"); nclose  = gsub(/}/, "}"); print; if(nopen > 0 amp;amp; nclose == nopen) { exit; } }' $file > $file.new
done
 

Здесь мы подсчитываем количество открытых и закрытых скобок, мы заканчиваем, если число {‘s равно числу}. Функция awk::gsub() позволяет нам подсчитывать вхождения данного символа в строку. Эта основная команда unix может обрабатывать даже файлы json с некоторыми синтаксическими ошибками. Поскольку вы не можете вручную исправить все эти файлы с помощью редактора vi.

Комментарии:

1. Нужно больше кавычек, чтобы быть в безопасности со всеми возможными именами файлов. Кроме того, вам, вероятно, нужно сопоставлять } только начало строки, так как в противном случае закрывающие фигурные скобки могут появиться и раньше в файле.

2. Предполагается, что } заканчивает строку, после нее нет данных, но ей может предшествовать любое количество символов. Похоже, это относится и к ОП.

3. Проблема в том, что у нас может быть { "vulnerabilities": [{"name": "vuln-1", "metadata": "other"}, {"name": "vuln-2"}], "other": "fields"} … вы не захотите отключаться после other"} . AFAICT ОП не предоставил достаточно подробностей, чтобы в любом случае быть уверенным в том, как выглядят их данные.

4. @Чарльз Даффи, вы правы, этот код будет работать только для очень простого json, json-подобного, json-ошибочного файла.

5. Рассмотрим в качестве альтернативного ответа, который принимает только первый документ JSON в потоке из нескольких, jq -n 'input' . (Не добавляя его сам, потому что мне неудобно отвечать на такой неполный вопрос-у меня нет того уровня уверенности, который был бы, если бы у нас была правильная спецификация формата данных операции).