Когда Вы уже получили ответ от @mdpc, который я просто обеспечу мнению Вашей исходной проблеме. Я не шел бы по этой дороге, поскольку это открывает кучу проблем, и Ваши программы в целом должны работать на всех системах (также проверка, если Ваша система все еще работает, если Вы работаете в другом локальном). Вы не должны также действительно полагаться на вывод/команды самостоятельно, но использовать соответствующий API для получения доступ/изменения к информации.
Так или иначе вот некоторые пути, которые могли помочь смягчить Вашу проблему:
Поскольку Вы пометили этот python
и предположили, что файл json
имеет имя x.json
import os, json
with open('x.json') as f:
x = json.load(f)
print '{}{}{}'.format(', '.join(y['displayName'] for y in x['data']), os.linesep,
', '.join(y['value'] for y in x['data']))
First Name, Last Name, Position, Company Name, Country
VALUE, VALUE, VALUE, VALUE, VALUE
Хотя мне пришлось удалить последнюю запятую во входных данных Вашего примера, чтобы он заработал, потому что jq
жаловался на ожидание другого элемента массива, это:
INPUT | jq -r '[.[][].displayName], [.[][].value]| join(", ")'
... заставило меня.....
First Name, Last Name, Position, Company Name, Country
VALUE, VALUE, VALUE, VALUE, VALUE
Как это работает в двух словах:
[]
индексного поля и .dot
нотацию. .[][][].displayName
. [.[][].displayName], [.[][].value]
join(", ")
, чтобы они были объединены как отдельные сущности. На самом деле выполнение [.field]
- это всего лишь другой путь к map(.field)
, но это немного более специфический способ, так как он задает уровень глубины для получения желаемых данных.
В дополнение к уже предложенным причинам, это может быть также следующим образом:
du -md 1
снова. Исправьте ситуацию, переместив скрытую папку в другое место или установите в другое место. Учитывая только этот файл, вы можете сделать что-то вроде:
<testfile jq -r '.data | map(.displayName), map(.value) | join(", ")'
. Оператор
выбирает поле из объекта/хэша. Таким образом, мы начинаем с .data
, который возвращает массив с данными в нем. Затем дважды сопоставляем массив, сначала выбирая displayName, затем выбираем значение, давая нам два массива с только значениями этих ключей. Для каждого массива мы соединяем элементы с «», образуя две строки. Аргумент -r
указывает jq
не цитировать результирующий последовательности.
Если ваш фактический файл длиннее (т.е. содержит записи для более чем одного человека), вам, вероятно, потребуется что-то немного сложнее.
-121--7553- Я обнаружил, что jq
трудно обернуть голову. Вот некоторые Ruby:
ruby -rjson -rcsv -e '
data = JSON.parse(File.read "file.json")
data["data"].collect {|item| [item["displayName"], item["value"]]}
.transpose
.each {|row| puts row.to_csv}
'
First Name,Last Name,Position,Company Name,Country
VALUE,VALUE,VALUE,VALUE,VALUE
Синтаксический анализатор ruby JSON пробил про запятую перед закрывающей скобкой.
Учитывая только этот файл, вы можете сделать что-то вроде:
<testfile jq -r '.data | map(.displayName), map(.value) | join(", ")'
.
Оператор выбирает поле из объекта / хеша. Таким образом, мы начинаем с .data
, что возвращает массив с данными в нем. Затем мы дважды отображаем на массиве, сначала выбирая имя отображения, а затем выбирая значение, давая нам два массива только с значениями этих клавиш. Для каждого массива мы присоединяемся к элементам с «», образуя две строки. Аргумент -R
-R
JQ
не процитировать полученные строки.
Если ваш фактический файл дольше (т. Е. Есть записи для более чем одного человека), вы, вероятно, понадобится что-то более сложное.
jq имеет фильтр @csv для преобразования массива в строку CSV. Этот фильтр учитывает большинство сложностей, связанных с форматом CSV, начиная с запятых, встроенных в поля. (jq 1.5 имеет аналогичный фильтр, @tsv, для создания файлов значений, разделенных табуляцией.)
Конечно, если все заголовки и значения гарантированно свободны от запятых и двойных кавычек, тогда может не быть необходимо использовать фильтр @csv. В противном случае, наверное, лучше было бы его использовать.
Например, если «Название компании» было «Смит, Смит и Смит», и если другие значения были такими, как показано ниже, вызов jq с параметром «-r» приведет к созданию действительного CSV:
$ jq -r '.data | map(.displayName), map(.value) | @csv' so.json2csv.json
"First Name","Last Name","Position","Company Name","Country"
"John (""Johnnie"")","Doe","Director, Planning and Posterity","Smith, Smith and Smith","Transylvania"
При каждом изменении конфигурации добавьте суффикс, кратко описывающий конфигурацию, в поле EXTRAVERSION
файла Makefile.
EXTRAVERSION=-lpae
и другое время
EXTRAVERSION=-486
Что пути различные конфигурации являются различными версиями, поскольку задействованы все инструменты: разные выходные данные из uname -r
, различные подкаталоги в /lib/modules
и т. д.
Именно это делают большинство дистрибутивов.
-121--184840-Ответ дан в комментарии перечислять рассылки Штефана Дёсингера под названием Wine 64 bit
-121--54778-OSX имеет ABI несовместимость с Win64 - OSX перезаписывает регистр CPU, который Win64 приложения ожидают, что останется нетронутым. Apple не может изменить ABI, так как уже существуют 64-разрядные приложения OSX, которые ожидают, что все будет работать путь. Потенциальным обходным путем может быть запуск Wine внутри эмулятора CPU, как qemu, но это все, кроме просто.
Я предпочитаю делать каждую запись строкой в моем CSV.
jq '.data | map([.displayName, .rank, .value] | join(", ")) | join("\n")'
Мне нравится jq , но это не инструмент для преобразования JSON в CSV. Чтобы сделать что-нибудь с CSV, рассмотрите:
Эта запятая после последнего объекта («Страна» )в массиве создает проблемы для jq , поэтому я удалил ее вручную.
Вот полный конвейер для получения желаемого результата,
% jq '.data' < so.json # Get just the array of objects
| in2csv -f json -I # Convert array-of-objects to rows-with-fields
| gocsv transpose # "Rotate" table
| gocsv tail -n 1 # Cut out rank
| gocsv select -c 1 -exclude # Cut out JSON property names
и вы получите,
First Name,Last Name,Position,Company Name,Country
VALUE,VALUE,VALUE,VALUE,VALUE
После команды jq , которая просто приводит нас к данным, вот вывод на каждом этапе:
in2csv -f json -I
:
Каждый объект становится строкой, и каждое свойство объекта является его собственным полем; -I
чтобы не выводить типы данных (оставьте любое значение, поскольку -равно ).
displayName,rank,value
First Name,1,VALUE
Last Name,2,VALUE
Position,3,VALUE
Company Name,4,VALUE
Country,5,VALUE
gocsv transpose
:
Первый столбец становится заголовком, а каждый последующий столбец становится строкой.
displayName,First Name,Last Name,Position,Company Name,Country
rank,1,2,3,4,5
value,VALUE,VALUE,VALUE,VALUE,VALUE
gocsv tail -n 1
:
Начиная с нижнего ряда, сохранить "1 ряд вверх" (только этот нижний ряд ); эффективно вырезал ранг .
displayName,First Name,Last Name,Position,Company Name,Country
value,VALUE,VALUE,VALUE,VALUE,VALUE
gocsv select -c 1 -exclude
:
Наконец, исключите первый столбец; эффективное вырезание имен свойств объекта из исходного JSON.
First Name,Last Name,Position,Company Name,Country
VALUE,VALUE,VALUE,VALUE,VALUE
Старый вопрос, но кажется, что все ответы рекомендуют индексировать по displayName
, что для меня не имеет смысла. CSV — это не индексированный формат, это список строк, поэтому нелогично, что вам нужно что-то индексировать. Единственным исключением является https://unix.stackexchange.com/a/673753/488462, который я бы предпочел на практике, за исключением того, что он использует csvkit, а вопрос явно касается jq.
Так вот jq -единственный путь в два шага:
cat data.json | jq '.[0] | keys_unsorted | @csv' > data.csv
cat data.json | jq '.[] | map(values) | @csv' >> data.csv
Вы можете объединить их в одну команду с помощью tee
или создать сложный jq-запрос, который делает обе вещи, если хотите, но я думаю, что эта версия уже достаточно хороша.
Обратите внимание, что вы должны использовать keys_unsorted
, потому что keys
будет сортировать ваши ключи (, а values
не ), что приведет к несоответствию столбцов. Кроме того, хотя обычно людям нужны оба шага, технически формат CSV не требует заголовка -, это просто необязательное удобство (и не всегда желательно ). Таким образом, в этих случаях вы можете опустить заголовок.
Наконец, входные данные вашего примера без необходимости заключены в объект с именем data
. Я предполагаю, что вы распаковываете это с помощью тривиальной команды, такой как cat input.json | jq '.data' > data.json
, так как это не имеет отношения к тому, что запрашивается (для преобразования в CSV ).