Как экранировать ввод JSON?

cmd x>&y говорит :«перенаправить fd x на любой ресурс, на который перенаправляется fd y»

Так в:

cat 1>&3 3>&1

Вы говорите, что catfd 1 (stdout )должен обращаться к тому же ресурсу, что и открытый в fd 3, то есть ./tmpоткрыт в режиме чтения+записи; а затем fd 3 на тот же ресурс, что и open на fd 1, который вы только что сделали равным ./tmp.

Таким образом, catбудет запущен с обеими fds 1 и 3, перенаправленными на ./tmp. catничего не делает со своим fd 3, вы можете перенаправить fd 3 catна что угодно, это не будет иметь никакого эффекта.

Однако он записывает содержимое fileв свой fd 1, так что вы обнаружите, что содержимое fileзаписано в начале ./tmp.

cat fileзаписывает содержимое fileтолько один раз и только в один fd. Если вам нужно что-то, что дважды записывает содержимое fileв два разных файла fd, вместо этого вам нужно tee:

В

< file tee./tmp

teeбудет записывать то, что он читает из своего fd 0 (здесь перенаправлено на fileоткрыть в режиме чтения -только )в оба./tmp(открыть в режиме только записи с усечением )и его fd 1 (стандартный вывод ).

Хотя можно сказать teeоткрыть ./tmpв режиме добавления с помощью -a, вы не можете сказать ему открыть ./tmpв режиме чтения+записи без усечения, например 3<>.

Для этого вам понадобится:

< file tee /dev/fd/3 3<>./tmp

, который будет работать, кроме Linux, или прибегнет к использованию zshи его встроенной функции ти:

cat < file 3<>./tmp >&1 >&3 3>&-

Если fd 1 перенаправляется дважды, zsh, когда опция mulltiosвключена (включена по умолчанию ), будет выполнять внутренний тройник для пересылки вывода в оба назначения (путем запуска внутренний процесс, который считывает вывод catи записывает его в оба адресата ).

Временное использование fd 3 позволяет обойти проблему, которая в

cat < file >&1 1<>./tmp

zsh будет жаловаться на zsh: file mode mismatch on fd 1, так как предполагается, что вы хотите прочитать из ./tmp.

1
26.10.2019, 23:26
3 ответа
jq -R -s '.' < datafile

Это считывает все datafileкак строку, а затем jq просто распечатывает ее как строку JSON. Это даст вам строку в кавычках, подходящую для замены непосредственно в этом шаблоне содержимым datafile. Данные будут корректно заключены в кавычки JSON -с использованием только escape-последовательности RFC 7159 и будут находиться в одной большой строке, поскольку JSON не позволяет строковым литералам занимать несколько строк.


Вы также можете собрать весь документ в jq с файлом шаблона JSON и

jq --arg f "$(cat datafile)" '.["test.txt"].content = $f' < template.json

В самых последних версиях jqесть опция --rawfile f datafile, которую можно использовать для загрузки файла в строку вместо подстановки команд; вы также можете поменять местами -R --slurp --slurpfile t template.json datafileи t["test.txt"].content =..

4
27.01.2020, 23:40

Мне пришлось экранировать некоторые JSON для включения в другие JSON, и есть очень простое решение:

$ jq @json <<< '{"Hello": "World"}'
"{\"Hello\":\"World\"}"
2
23.08.2021, 22:39

Если у вас есть документ JSON в file.jsonи вы просто хотите вставить содержимое в нужное место, используя jq,

jq --rawfile content test.txt '."test.txt".content |= $content' file.json

Если содержимое должно быть закодировано в base64 -:

base64 test.txt | jq --rawfile content /dev/stdin '."test.txt".content |= $content' file.json

Создание JSON с нуля с использованиемjo(аппроксимации метаданных из выходных данных statиfile):

#!/bin/sh

gist_url='some url'
filename=test.txt

jo -p "$filename"="$( jo \
        filename="$filename" \
        type="$( file -b --mime-type "$filename" )" \
        language="$( file -b "$filename" )" \
        raw_url="$gist_url" \
        size="$( stat -c %s "$filename" )" \
        truncated=false \
        content=@"$filename" )"

Настройте утилиты statи fileв соответствии с вашим Unix (вышеприведенные варианты используют параметры Linux ).

Выход:

{
   "test.txt": {
      "filename": "test.txt",
      "type": "text/x-shellscript",
      "language": "POSIX shell script, ASCII text executable",
      "raw_url": "some url",
      "size": 108,
      "truncated": false,
      "content": "#!/bin/sh\n\n# comment\nfunc () {\n    for ((i=1;i<10;i++)); do\n        :\n    done\n}\n\nprintf '%s\\n' Foo bar baz"
   }
}

Используйте %"$filename"вместо @"$filename", чтобы получить значение в кодировке base64 -для клавиши content:

{
   "test.txt": {
      "filename": "test.txt",
      "type": "text/x-shellscript",
      "language": "POSIX shell script, ASCII text executable",
      "raw_url": "some url",
      "size": 108,
      "truncated": false,
      "content": "IyEvYmluL3NoCgojIGNvbW1lbnQKZnVuYyAoKSB7CiAgICBmb3IgKChpPTE7aTwxMDtpKyspKTsgZG8KICAgICAgICA6CiAgICBkb25lCn0KCnByaW50ZiAnJXNcbicgRm9vIGJhciBiYXoK"
   }
}
0
24.08.2021, 07:39

Теги

Похожие вопросы