
Я хочу отправить данные JSON с помощью httpie.
Если я использую двойные кавычки и экранирую двойные кавычки, окружающие ключ, то это работает.
json="[ \
{ \
\"count\": 3 \
} \
]"
echo $json
[ { "количество": 3 } ]
Но я не хочу убегать. Следующее проще скопировать и вставить, но это не работает.
json='[ \
{ \
"count": 3 \
} \
]'
echo $json
[ \ { \ "количество": 3 \ } \ ]
Итак, можно ли не экранировать двойные кавычки вокруг ключа JSON, чтобы его было легче копировать откуда-либо и вставлять?
решение1
В
var="foo\
bar"
Последовательность \<newline>
является специальной внутри двойных кавычек, но не внутри одинарных кавычек и являетсяудаленный, поэтому $var
содержит foobar
.
Когда вы делаете:
echo $json
Вы используете оператор split+glob (неявный оператор, вызываемый, когда вы забываете заключить расширение в кавычки), то есть содержимое разделяется $json
на символы in $IFS
, и каждое слово подлежит генерации имени файла (т. н. глобализации).
Значение по умолчанию $IFS
содержит пробел, табуляцию и новую строку (а также пробел, табуляция и новая строка, как оказалось, получают специальную обработку в отношении разделения, поскольку любая их последовательность считается как один, а начальные и конечные игнорируются). Так, например, в:
var=' foo *
bar'
echo $var
$var
сначала делится на foo
, *
и bar
(расколотьчасть) и *
расширяется до списка не скрытых файлов в текущем каталоге (шарчасть).
Если вы хотите отобразить содержимое как есть (но учтите, что многие echo
реализации могут искажать содержимое), вы должны написать:
$ echo "$json"
[ { "count": 3 } ]
Теперь, если вы хотите сжать интервал, возможно, вы можете воспользоваться оператором split+glob.
json='
[
{
"count": 3
}
]'
unset -v IFS # make sure we get a default splitting behaviour.
# an unset -v IFS is equivalent to IFS=$' \t\n'
set -o noglob # disable the glob part
echo $json # use the split+glob operator
echo
выводит свои аргументы, разделенные пробелами, так что каждая последовательность пробелов, табуляции или символов новой строки будет фактически заменена одним символом пробела (за исключением начальных и конечных, которые будут удалены, и echo
добавляет один символ новой строки в конце). Таким образом, вы получите:
[ { "count": 3 } ]
В любом случае, это не будет различать, находятся ли пробелы в кавычках или нет, поэтому это может изменить смысл данных JSON ( "foo bar"
будут преобразованы, "foo bar"
например, в ).
Если вы хотите использовать \<newline>
последовательность для экранирования (удаления) символов новой строки, но при этом сохранить другие пустые символы и при этом не экранировать символы двойных кавычек, вы можете использовать here-document:
json=$(cat <<EOF
[\
{\
"count": 3\
}\
]
EOF
)
echo "$json"
Что дало бы:
[ { "count": 3 } ]
(символы новой строки были удалены (некоторые из них можно было сохранить, не добавляя к ним обратную косую черту), но остальные пробелы остались нетронутыми).
решение2
Нет необходимости в обратных косых чертах для продолжения строк внутри кавычек. Во втором примере обратные косые черты активно вредны, потому что внутри одинарных кавычек они будут сохранены как таковые, что сделает строку синтаксически недействительной. Просто избавьтесь от обратных косых черт, и это заработает.