❯ jq --version
jq-1.6
Я использую файл .jq в качестве фильтра, как показано ниже, он работает:
❯ cat jq/script.jq
def fi(v):
v | tostring |
if test("\\.") then
"float"
else
"integer"
end;
def estype(v):
if type= = "number" then
fi(v)
else
type
end;
def esprop(v):
if type= = "object" then
{"properties": v | with_entries(.value |= esprop(.))}
else
{"type": estype(v)}
end;
with_entries(.value |= esprop(.))
❯ cat test.json | jq -f jq/script.jq
...(omit results)
Но когда я использую его как библиотеку, он выдает ошибку:
# comment the last filter, except the definitions of functions
❯ cat jq/script.jq
def fi(v):
v | tostring |
if test("\\.") then
"float"
else
"integer"
end;
def estype(v):
if type= = "number" then
fi(v)
else
type
end;
def esprop(v):
if type= = "object" then
{"properties": v | with_entries(.value |= esprop(.))}
else
{"type": estype(v)}
end;
# with_entries(.value |= esprop(.))
❯ cat test.json | jq -L jq/script.jq 'import script;'
jq: error: syntax error, unexpected IDENT, expecting FORMAT or QQSTRING_START (Unix shell quoting issues?) at <top-level>, line 1:
import script;
jq: 1 compile error
Что это значит и как я могу отладить и исправить это?
Являются ли файлы .jq фильтром или библиотека имеет другой синтаксис (не похоже на это)?
@Philippe В руководстве в разделе Модули говорится: «Например, с -L$HOME/.jq
модуль foo
можно найти в $HOME/.jq/foo.jq
и $HOME/.jq/foo/foo.jq
. Если $HOME/.jq
является файлом, он загружается в основную программу».
@pmf Я имел в виду, что -L jq/script.jq
не работает, а -L jq
работает.
syntax error, unexpected IDENT, expecting FORMAT or QQSTRING_START
Это означает, что синтаксический анализатор нашел идентификатор там, где ожидал строку. (FORMAT — это токен для средства форматирования, такого как @csv
или @text
, а QQSTRING_START — это токен для строки, например "script"
. На практике здесь бесполезно использовать средство форматирования, поскольку оно не позволит вам использовать непостоянную строку, но парсер этого не знает.)
Вероятно, проще всего вернуться к руководство по эксплуатации. В нем говорится, что форма, ожидаемая для «импорта»,
import RelativePathString as NAME;
и форма, ожидаемая для «включить»,
include RelativePathString;
Не хватает примеров, чтобы сделать это на 100% понятным, но «RelativePathString» является заполнителем — это должна быть буквальная строка. Попробуйте один из них:
cat test.json | jq -L jq 'include "script"; with_entries(.value |= esprop(.))'
cat test.json | jq -L jq 'import "script" as script; with_entries(.value |= script::esprop(.))'
Обратите внимание, что путь к библиотеке должен быть каталогом, содержащим ваш скрипт, и разница между include и import.
Они используют один и тот же синтаксис. Проблема была с оператором импорта, а не с файлом сценария.
Можно ли как-то предоставить файл модуля напрямую с опцией, как в ОП -L jq/script.jq
? Потому что в примере с использованием -L$HOME/.jq
в руководстве в разделе Модули говорится: «Если $HOME/.jq
является файлом, он загружается в основную программу».
@pmf Я не вижу способа сделать это. Я думаю, что это заявление в руководстве является констатацией факта, относящегося к системе модулей, а не иллюстрацией. Насколько я могу судить, явно читается как $HOME/.jq
и больше ничего подобного.
-L
принимает в качестве аргументаdirectories
, а не файлы.