如何从其他命令的输出中动态地建立一个bash对话框?

问题描述 投票:0回答:1

上下文

我想用我的时间战士数据建立一个对话框,这样我就可以直接选择我要回溯的内容,而不是选择 timew s :ids filter_tag那么 time cont @12.

因此,首先我创建了数据集,试图填充Dialog选项。

timew s :ids $(date -I -d'8 days ago') - $(date -I -d'tomorrow') |
    # most recent first, only the top 30 (4 additional lines are decoration)
    tac | head -n 34 |
    # format the whole thing as '1 "some label "' and so on
    sed -ne 's:.*@::p' |
    sed -e 's|\s\+[0-9]\+:.*| |g' -e's:\s\+: ":' -e's:\s*$:":' -e's:^: :'

这将产生如下的报告。

 1 "some_info, some_info"
 2 "some_info, some_info"
 3 "some_info, some_info"
 4 "some_info"
 5 "some_info, some_info"
 6 "some_info, some_info, some_info"
 7 "some_info, some_info"
 8 "some_info, some_info-some_info, some_info, some_info"
 9 "some_info, some_info"
 10 "some_info, some_info-some_info, some_info, some_info"
 11 "some_info, some_info"
 12 "some_info, some_info"
 13 "some_info"
 14 "some_info, some_info"
 14 "some_info, some_info"
 15 "some_info, some_info, some_info"
 16 "some_info, some_info, some_info, some_info, some_info, some_info"
 17 "some_info, some_info, some_info"
 18 "some_info"
 19 "some_info, some_info"
 20 "some_info"
 21 "some_info, some_info, some_info, some_info, some_info, some_info"
 22 "some_info, some_info"
 23 "some_info, some_info, some_info, some_info, some_info, some_info"
 24 "some_info, some_info45, some_info some_info some_info, some_info"
 25 "some_info"
 26 "some_info"
 27 "some_info, some_info, some_info"
 28 "some_info, some_info, some_info, some_info"
 29 "some_info, some_info, some_info"
 30 "some_info"

对话框框架

所以我找到了这个脚手架

#!/bin/bash

HEIGHT=15
WIDTH=40
CHOICE_HEIGHT=4
BACKTITLE="Backtitle here"
TITLE="Title here"
MENU="Choose one of the following options:"

OPTIONS=(1 "Option 1"
         2 "Option 2"
         3 "Option 3")

CHOICE=$(dialog --clear \
                --backtitle "$BACKTITLE" \
                --title "$TITLE" \
                --menu "$MENU" \
                $HEIGHT $WIDTH $CHOICE_HEIGHT \
                "${OPTIONS[@]}" \
                2>&1 >/dev/tty)

clear
case $CHOICE in
        1)
            echo "You chose Option 1"
            ;;
        2)
            echo "You chose Option 2"
            ;;
        3)
            echo "You chose Option 3"
            ;;
esac

问题

所以我天真地认为,使用 OPTIONS=( $(timew s :ids $(date -I -d'8 days ago') - $(date -I -d'tomorrow') | tac | head -n 34 | sed -ne 's:.*@::p' | sed -e 's|\s\+[0-9]\+:.*| |g' -e's:\s\+: ":' -e's:\s*$:":')) 作为之前代码中的替换就可以了。但似乎引号不会那么容易被考虑到。我试着用各种方法来解决这个问题,包括在一个 while read 循环和使用 外壳参数扩展:${variable@Q}。以及其他可怕的东西,但没有找到任何可以用的东西。

疑问

我如何正确填充对话框选项与我的Timewarrior输出的输出?

bash dialog quotes
1个回答
1
投票

这应该可以达到你想要的效果。

#!/bin/bash

HEIGHT=15
WIDTH=40
CHOICE_HEIGHT=4
BACKTITLE="Backtitle here"
TITLE="Title here"
MENU="Choose one of the following options:"

generate_options(){
    cat << EOF
Option 1
Option 2
Option 3
EOF
}

declare -a OPTIONS
count=1
while IFS= read -r line; do
    OPTIONS+=( $((count++)) "$line" )
done < <(generate_options)

CHOICE=$(dialog --clear \
                --backtitle "$BACKTITLE" \
                --title "$TITLE" \
                --menu "$MENU" \
                $HEIGHT $WIDTH $CHOICE_HEIGHT \
                "${OPTIONS[@]}" \
                2>&1 >/dev/tty)

clear
case $CHOICE in
        1)
            echo "You chose Option 1"
            ;;
        2)
            echo "You chose Option 2"
            ;;
        3)
            echo "You chose Option 3"
            ;;
esac

你只需要替换 cat 命令与你的命令(行首不加数字)。

所以这个问题的完整解决方案是。

#!/bin/bash

HEIGHT=40
WIDTH=80
CHOICE_HEIGHT=30
BACKTITLE="Timewarrior"
TITLE="Resume Selector"
MENU="Select task to resume"

generate_options(){
  # events of the last week, filtered by $@
  timew s :ids $(date -I -d'8 days ago') - $(date -I -d'tomorrow') "$@" |
    # most recent first, keep only a 60 entry buffer
    tac | head -n 60 |
    # format the whole thing as '1 some labels' and so on
    sed -ne 's:.*@::p' |
    sed -e 's|\s\+[0-9]\+:.*| |g' -e's:^: :' |
    # keep only 30 entries
    uniq | head -n 30
}

declare -a OPTIONS
while IFS= read -r line; do
  bid=$(echo "$line" | awk '{print $1}')
  peg=$(echo "$line" | sed 's:[0-9]\+\ \+::')
  # get ride of duplicates
  case "${OPTIONS[@]}" in  *"$peg"*) continue ;; esac
  OPTIONS+=( "$bid" "$peg" )
done < <(generate_options "$@")

CHOICE=$(dialog --clear \
                --backtitle "$BACKTITLE" \
                --title "$TITLE" \
                --menu "$MENU" \
                $HEIGHT $WIDTH $CHOICE_HEIGHT \
                "${OPTIONS[@]}" \
                2>&1 >/dev/tty)

clear
if [[ -z $CHOICE ]] ; then
  exit
fi
timew cont "@$CHOICE"
© www.soinside.com 2019 - 2024. All rights reserved.