Как говорили другие, гораздо лучше использовать язык, (такой как perl, python или ruby ), которые имеют библиотеки для синтаксического анализа json, или специальный -целевой инструмент, который делает это как jq
... но если вы действительно хотите или должны обрабатывать данные json с помощью обычных инструментов, таких как awk
или sed
, вам сначала нужно преобразовать их в формат, ориентированный на строку -.
Почему? Потому что вы не можете надежно анализировать json только с помощью регулярных выражений, и даже если вы думаете, что преуспели, то, что у вас есть, будет невероятно хрупким и склонным к поломке даже при незначительных изменениях ожидаемого ввода.
jsonpipe
(, написанный на python ), является одним из таких инструментов, который может выполнять преобразование в формат, ориентированный на строку -. например. после исправления сломанного json в вашем примере он выдает следующий вывод:
$ jsonpipe < /tmp/nick.json
/ {}
/content []
/content/0 {}
/content/0/JOB_STATUS_ID 283739
/content/0/PROGRAM_ID 57
/content/0/STATUS "Completed"
/content/0/**DATA_DATE** "2017-03-09 00:00:00"
/content/0/**START_TIME** "2017-03-10 00:46:13"
/content/0/END_TIME "2017-03-10 00:56:40"
/content/0/TOTAL_ROWS null
/content/0/UPDATED_ROWS null
/content/0/DELETED_ROWS null
/content/0/INSERTED_ROWS null
/content/0/REF1 "NULL"
/content/0/REF2 "NULL"
/content/0/AUD_CREATE_DT "2017-03-10 00:46:13"
/content/0/AUD_CREATE_USER "JOB_CONTROL"
/content/0/AUD_MODIFY_DT "2017-03-10 00:56:40"
/content/0/AUD_MODIFY_USER "JOB_CONTROL"
/content/1 {}
/content/1/JOB_STATUS_ID 109711
/content/1/PROGRAM_ID 57
/content/1/STATUS "Completed"
/content/1/DATA_DATE "2017-01-11 00:00:00"
/content/1/START_TIME "2017-01-12 16:55:14"
/content/1/END_TIME "2017-01-12 18:54:51"
/content/1/TOTAL_ROWS null
/content/1/UPDATED_ROWS null
/content/1/DELETED_ROWS null
/content/1/INSERTED_ROWS null
/content/1/REF1 "NULL"
/content/1/REF2 "NULL"
/content/1/AUD_CREATE_DT "2017-01-12 16:55:14"
/content/1/AUD_CREATE_USER "JOB_CONTROL"
/content/1/AUD_MODIFY_DT "2017-01-12"
Это позволяет обрабатывать его с помощью стандартных утилит обработки текста. Например:
$ jsonpipe < /tmp/nick.json | \
sed -ne 's:^/content/0/\*\*DATA_DATE\*\*[[:space:]]\+::p'
"2017-03-09 00:00:00"
$ jsonpipe < /tmp/nick.json | \
awk -F'"' '/^\/content\/0\// && /DATA_DATE/ {print $2}'
2017-03-09 00:00:00
или даже что-то столь грубое, как это:
$ jsonpipe < /tmp/nick.json | grep '/0/.*DATA_DATE'
/content/0/**DATA_DATE** "2017-03-09 00:00:00"
В debian и производных системах он упакован как python-jsonpipe
и, вероятно, имеет похожее имя пакета в других дистрибутивах. Или его можно найти по адресуhttp://pypi.python.org/pypi/jsonpipe
ПРИМЕЧАНИЕ. :он поставляется с соответствующим jsonunpipe
инструментом, который вы можете использовать для преобразования этого формата, ориентированного на строку -, обратно в json -, например. после изменения его с помощью sed
или awk
или чего-то еще.
Год спустя, вот мое решение с использованием ловушек.Отображает имя хоста, corrent PWD
и команду (и содержимое экрана, если на экране ). Это легко настроить в set_screen_window
ниже. Все должно находиться в вашем .bashrc
.
Сначала какая-нибудь вспомогательная функция, чтобы проверить, включен ли я screen
или нет:
export PROMPT_COMMAND=''
if [[ "$TERM" == "screen"* ]]; then
screen_title_slicer() { echo "${1:0:40}"; } # Arbitrary cut off. use echo $1 for full.
screen_title_format='\ek%s\e\\'
else
screen_title_slicer() { echo "${1//[^[:print:]]/}"; }
screen_title_format='\033]0;%s\007'
fi
Суть построения команды, опираясь на полезное BASH_COMMAND
. Я делаю некоторые пользовательские вещи для fg
(, такие как отображение исходной команды )и cd
(, чтобы получить реальный каталог ):
ready="Ready!"
set_screen_window() {
title_string=$1
[ -z "$title_string" ] && title_string=$(screen_title_slicer "$BASH_COMMAND")
[ "$title_string" = "fg" ] && read -ra job < <( jobs %% 2> /dev/null )
[ "$title_string" = "fg " ] && read -ra job < <(jobs "${title_string:3} 2> /dev/null")
if [ ${#job[@]} -gt 0 ]; then
title_string=$(screen_title_slicer "${job[2]}")
fi
cwd=$PWD
if [ "${title_string::3}" = "cd " ]; then
cwd=$( eval cd "$(awk '{print $2}' <<< "$BASH_COMMAND")" &> /dev/null && pwd)
[ -z "$cwd" ] && cwd=$PWD
title_string="$ready"
fi
[ "$title_string" = "cd" ] && title_string=$ready && cwd=$HOME
printf "$screen_title_format" "$HOSTNAME -- ${cwd//$HOME/\~}> $title_string" > "$(tty)"
unset job
unset title_string
}
Теперь инициализируйте головку терминала моей строкой ready
и перехватите как ошибку, так и отладку, чтобы обновить окно терминала:
set_screen_window "$ready"
trap "set_screen_window $ready" ERR
trap set_screen_window DEBUG
Наконец, в .vimrc
у нас есть vim
специфический материал:
function! Filename()
if @% == ""
return "noname"
endif
let is_tracked=system("git ls-files ". expand("%"))
if is_tracked == ""
return expand("%:t")
endif
return gitbranch#name(). "/". expand("%:t")
endfunction
let &titlestring = hostname(). " -- vim ". Filename()
if &term[:5] == "screen"
set t_ts=^[k
set t_fs=^[\
set title
endif
autocmd TabEnter,WinEnter,BufReadPost,FileReadPost,BufNewFile * silent execute '!printf "\033]0;'.hostname().' -- vim '.Filename().'\007"'
autocmd TabEnter,WinEnter,BufReadPost,FileReadPost,BufNewFile * let &titlestring = hostname(). ' -- vim '. Filename()
Здесь Filename
можно настроить, чтобы получить собственный вариант заголовка. autocmd
обеспечивает перезагрузку при перемещении между буферами, окнами и т.п. gitbranch
в моем примере доступен плагин для git
генерации (как и следовало ожидать )имени ветки при редактировании файлов в репозиториях.
использование PROMPT_COMMAND='/bin/echo -ne "\033k\033\0134"'
в .bashrc
вместе с shelltitle '$ |bash'
в .screenrc
отлично работает для меня. Использование этого конкретного PROMPT_COMMAND
каким-то образом ломает мою PS1, поэтому я также добавил следующее в.bashrc
:
case "$TERM" in
screen*) PROMPT_COMMAND='/bin/echo -ne "\033k\033\0134"';;
esac
Пример прикрепленного изображения -запуск сна в окне 0, поиск в окне 1, просмотр в окне 2, проверка связи в окне 3 и bash в окне 4.