Отображать полную команду на экране GNU с bash в заголовке и правильно взаимодействовать с буферами Vim

Как говорили другие, гораздо лучше использовать язык, (такой как 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или чего-то еще.

0
26.01.2020, 11:06
2 ответа

Год спустя, вот мое решение с использованием ловушек.Отображает имя хоста, 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генерации (как и следовало ожидать )имени ветки при редактировании файлов в репозиториях.

1
28.04.2021, 23:28

использование 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.enter image description here

1
28.04.2021, 23:28

Теги

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