#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'
. (Не добавляя его сам, потому что мне неудобно отвечать на такой неполный вопрос-у меня нет того уровня уверенности, который был бы, если бы у нас была правильная спецификация формата данных операции).