Я новичок в программировании оболочки, поэтому, возможно, я испортил свои цитаты.
Вот и все.
Похоже, вы добавили один слой цитат слишком много.
В рыбе (и большинстве других оболочек, включая, например, bash и zsh), кавычки являются специальными для оболочки только при буквальном использовании.
Это означает, что когда переменная содержит "some string"
, тогда echo $variable
напечатает "some string"
- это означает, что команда echo
получила строку с кавычками (примечание: bash также будет применяться разделение слов здесь, так что на самом деле он получит "some
и string"
, даже если вы можете предположить, что оно заключено в кавычки).
Я бы посоветовал вам пройтись по вашей функции по очереди и просто echo
переменные. Тогда представьте, что вы передали эту точную строку jq
- это сработает?
например. $key_names
бит:
set key_names (for key in $argv[2..-1]; echo "\\\"$key\\\""; end)
Цель этого, очевидно, состоит в том, чтобы экранировать все ключи (которые являются аргументами начиная со второго) для использования с jq
. Это означает, что они должны быть указаны один раз . Их не нужно заключать в кавычки во второй раз, потому что оболочка не заботится о не буквальных кавычках.
Так что любая клавиша должна выглядеть как "key"
.
Но когда мы ставим
printf '%s\n' $key_names
(который будет печатать каждую клавишу в отдельной строке)
после этого мы видим
\"bar\"
\"baz\"
\"qux\"
Это два слоя цитирования! Сами кавычки и обратные слэши, ускользающие от них.
Итак, давайте удалим один:
set key_names (для ключа в $ argv [2 ..- 1]; echo "\" $ key \ ""; end)
Это приведет к "bar"
, "baz"
и "qux"
.
(Это можно упростить до set key_names \"$argv[2..-1]\"
, используя декартово произведение рыбы )
Теперь для следующего бита:
set jq_args "\"with_entries(select([.key] | inside([$key_names_joined])))\""
Ваше намерение здесь состоит в том, чтобы выполнить это, как если бы вы имели
jq -r "with_entries(select([.key] | inside([\"bar\",\"baz\",\"qux\"])))" foo.json
В командной строке. Но когда вы используете переменные, вам не нужно снова заключать строку в них в кавычки - все расщепления и другие раскрытия уже произошли после присвоения значения, и больше не происходит при замене переменной.
Так что просто удалите экранированные кавычки
set jq_args "with_entries(select([.key] | inside([$key_names_joined])))"
и ваша функция должна работать.
Результат:
function jq_select_keys --description 'Selects given keys from json input'
set key_names \"$argv[2..-1]\"
set key_names_joined (string join "," $key_names)
set jq_args "with_entries(select([.key] | inside([$key_names_joined])))"
echo "Command: jq -r $jq_args $argv[1]"
jq -r $jq_args $argv[1]
end