Ключом к простому решению является общая функция aggregate_by
:
# In this formulation, f must either always evaluate to a string or
# always to an integer, it being understood that negative integers
# might be problematic
def aggregate_by(s; f; g):
reduce s as $x (null; .[$x|f] += [$x|g]);
Если CSV можно точно проанализировать, просто разделив запятые, тогда желаемое преобразование может быть выполнено с помощью следующего jqфильтр:
aggregate_by(inputs | split(","); .[0]; .[1])
Предполагается, что jq вызывается с опциями -R (raw) и -n.
Выход
При заданном входе CSV выход будет:
{
"b00nw33": [
"harrypotter788.flv",
"harrypotter788.mov",
"levitation271.avi"
],
"b01spider": [
"schimbvalutar109.avi"
]
}
Обработка нетривиального CSV
Приведенное выше решение предполагает, чтоCSV так же несложен, как и образец.Если, наоборот, CSV не может быть точно проанализирован путем простого разделения на запятые, потребуется более общий анализатор.
Одним из подходов было бы использование очень надежного и быстрого синтаксического анализатора csv2json на https://github.com/fadado/CSV
В качестве альтернативы, вы можете использовать один из многих доступных синтаксических анализаторов "csv2tsv" для генерации TSV, который может использовать jqобрабатывать напрямую (путем разделения на вкладки, то есть split("\t")
, а не split(",")
).
В любом случае, после преобразования CSV в JSON можно использовать определенный выше фильтр aggregate_by
.
Если вас интересует анализатор jq для CSV, вы можете захотетьсмотреть на fromcsvfile
(https://gist.github.com/pkoppstein/bbbbdf7489c8c515680beb1c75fa59f2);, см. также определения для fromcsv
, предлагаемые на https://github.com/stedolan/jq/issues/1650#issuecomment-448050902