Pregunta

I want to call dialog à la:

dialog --menu Choose: 0 40 10 A '' B '' C ''

except A, B and C are the result of a dynamic query, for the sake of this question the latter being { echo A; echo B; echo C; }.

I can get the desired command line seemingly by:

{ echo A; echo B; echo C; } | sed -e "s/\$/ ''/;"

but:

echo $({ echo A; echo B; echo C; } | sed -e "s/\$/ ''/;")

and its output:

A '' B '' C ''

show that the result of the command substitution is only word-split, but '' isn't interpreted as an empty argument, but passed verbosely to echo (and thus, dialog wouldn't display no descriptions for the menu items, but literally ''s).

I can work around this in bash using arrays, but is there a simpler solution I'm missing?

Given

$ e() { printf "tag: [$1] item: [$2]"; }
$ e $(echo "A ''")
$ tag: [A] item: ['']

How can I change the $(...) part, such that the item is [] instead of [''].

¿Fue útil?

Solución 2

You can change the IFS (internal field separator)

$ IFS=, e $(echo "a,,")
tag: [a] item: []

Seems to work. Is it nice? I do not know but would give some array magic a try. By the way, you can often use ${parameter/pattern/string} for substitution instead of calling sed. Unfortunately it only operates on a variable, which makes it less usable.

Otros consejos

Nice question.

I don't know if this qualifies as "simpler" but it has a certain elegance:

with-tags() {
  local line
  if read -r line; then with-tags "$@" "$line" ""; else "$@"; fi
}

{ echo A; echo B; echo C; } |
with-tags dialog --menu Choose: 0 40 10

It's easily extensible to handle input lines of the form TAG <optional description>:

with-tag-lines() {
  local tag desc
  if read -r tag desc; then with-tag-lines "$@" "$tag" "$desc"; else "$@"; fi
}

{ echo A with optional description; echo B; echo C; } |
with-tag-lines dialog --menu Choose: 0 40 10

You can try this:

cmd="dialog --menu Choose: 0 40 10 "
arg="`echo $({ echo A; echo B; echo C; } | sed -e "s/\$/ ''/;")`"
eval "${cmd}${arg}"

But I think that sed not required here. You can keep it simple:

cmd="dialog --menu Choose: 0 40 10 "
arg="`echo A \'\' B \'\' C \'\'`"
eval "${cmd}${arg}"
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top