Вы можете сделать это с помощью 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
Предполагается, что 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]
Вы можете использовать ассоциативный массив:
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"
)
Не так сложно (Я полагаю, показанный текст находится в каком-то файле, скажем, 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
установите разделитель строк на }
, разделитель полей на :
и составьте вывод. Там могут быть оставлены некоторые запятые в конце, которые вы можете легко удалить.
Я не уверен, что правильно вас понял, но если намерение состоит в том, чтобы создать переменные из содержимого .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