Разделите новые символы новой строки и цитаты из массива JSON и устанавливают определенные строки в качестве переменных через Bash

Вы можете сделать это с помощью awk:

{
  # extract files names form first line
  if (1 == NR) {
    num_fields = NF       
    for(i = 1; i <= num_fields ; i++)
    {
      # get line header
      header[i] = $i
      # create file name
      file[i] = "file-"i
    }
  }
  else 
  {
    # extract data if not first line
    for (i = 1; i <= num_fields; i++)
    {
      print header[i] ":" $i > file[i]
    }          
  }
}

И вызвать его с помощью:

awk -f script.awk file_to_process
0
23.10.2018, 14:52
4 ответа

Предполагается, что Description:...часть сообщения представляет собой одну строку, а заголовки имеют каноническую форму (нет " subJECT :hey", пожалуйста ).

Он использует спецификацию формата jq's @shдля экранирования своего вывода способом, подходящим для оболочки (с одинарными кавычками ). Спасибо @Stéphane Chazelas за исправления.

parse_json(){
  jq=$(jq -r '[.Email,.ID,(.details.message | split("\n")) | @sh] | join(" ")' -- "$1")
  eval "set -- $jq"
  email=$1; shift
  id=$1; shift
  for l; do
    case $l in
    "Your name: "*) name="${l#*: }";;
    "Subject: "*) subject="${l#*: }";;
    "Description: "*) description="${l#*: }";;
    # remove the following line if you want the.Email from json instead
    "Email: "*) email="${l#*: }";;
    esac
  done
  echo "id={$id}"
  echo "name={$name}"
  echo "email={$email}"
  echo "subject={$subject}"
  echo "description={$description}"
}

fz:/tmp% parse_json a.json
id={5930}
name={john doe}
email={johndoe@xxxxxxx.com}
subject={I need help with this}
description={I can find the download for the manual but I can only find the free updater for Windows or Mac. Can you help me please as I have a chrome notebook and Moto smart phone. Thank you. John doe

case... esacвыше может быть заменен чем-то, что будет создавать переменные с теми же именами, что и заголовки с буквенно-цифровыми символами, отличными от -, замененными символами подчеркивания. Это будет работать только с оболочками, поддерживающими замены ${var//pat/repl}(bash, zsh, ksh93):

.
parse_json(){
  jq=$(jq -r '[.Email,.ID,(.details.message | split("\n")) | @sh] | join(" ")' -- "$1")
  eval "set -- $jq"
  Email=$1; shift
  ID=$1; shift
  for l; do
    v="${l#*: }"; k="${l%%: *}"; eval "${k//[!a-zA-Z0-9]/_}=\$v"
  done
}

show_vars(){
  for v in ID Your_name Email Subject Description; do
    eval "echo \"$v=[\$$v]\""
  done
}

fz:/tmp$ parse_json a.json
fz:/tmp$ show_vars
ID=[5930]
Your_name=[john doe]
Email=[johndoe@xxxxxxx.com]
Subject=[I need help with this]
Description=[I can find the download for the manual but I can only find the free updater for Windows or Mac. Can you help me please as I have a chrome notebook and Moto smart phone. Thank you. John doe]
5
28.01.2020, 02:14

Вы можете использовать ассоциативный массив:

typeset -A field="($(jq -r '
   "[ID]=" + (.ID|@sh),
   (.details.message|capture("(?m)^(?<t>.*?): (?<v>.*)"; "g")|
     "["+(.t|@sh)+"]="+(.v|@sh))' file.json))"

Тогда у вас будет ID в ${field[ID]}, тема в ${field[Subject]}...

В вашем примере typeset -p fieldвыводит:

declare -A fields=(
  [Description]="I can find the download for the manual but I can only find the free updater for Windows or Mac. Can you help me please as I have a chrome notebook and Moto smart phone. Thank you. John doe"
  [ID]="5930"
  [Subject]="I need help with this"
  [Email]="johndoe@xxxxxxx.com"
  ["Your name"]="john doe"
)
2
28.01.2020, 02:14

Не так сложно (Я полагаю, показанный текст находится в каком-то файле, скажем, json.txtили вы можете отправить текст первому sedчерез канал):

sed s/'$'/:/ json.txt |\... добавить :в конце каждой строки

sed s/'\\n'/:/g |\... изменить любой \nна:

sed s/'"'//g |\... убрать кавычки

awk 'BEGIN{RS="}";FS=":"}{if($7){print "Name: "$3"\nEmail: "$5"\nSubject: "$17"\nDescription: "$19"\nID: "$7}}'

В awkустановите разделитель строк на }, разделитель полей на :и составьте вывод. Там могут быть оставлены некоторые запятые в конце, которые вы можете легко удалить.

0
28.01.2020, 02:14

Я не уверен, что правильно вас понял, но если намерение состоит в том, чтобы создать переменные из содержимого .details.message, я бы предложил следующее.

Первое извлечение .details.messageв необработанном режиме сjq:

jq -r '.details.message' in.json

Теперь проанализируйте это с помощью sed, чтобы сделать его bash -разборчивым:

parse.sed

/^Your name: /   s//uservar="/
/^Email: /       s//emailvar="/
/^Subject: /     s//subject="/
/^Description: / s//message="/
s/$/"/

Теперь вы можете использовать это в своем скрипте, например.:

. <(jq -r '.details.message' in.json | sed -f parse.sed)
echo $uservar, $emailvar

Выход:

john doe, johndoe@xxxxxxx.com
0
28.01.2020, 02:14

Теги

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