Операторы выбора оценивают к строкам

Я поймал ошибку функционального программирования, так естественно ничто больше не достаточно хорошо для меня.;)

Так, в ударе можно было записать:

case $status in
  "foo") status="bar" ;;
  "baz") status="buh" ;;
   *) status=$status ;;
esac

но я боюсь опечаток, таким образом, я предпочел бы писать:

status=case $status in
  "foo") "bar" ;;
  "baz") "buh" ;;
  *) $status ;;
esac

Вторая форма недопустима, так как случай оценивает к коду выхода последней выполняемой команды, которая нисколько не является, что я ищу.

Там легкие взломы к достижению, что я ищу?

11
задан codeforester 9 July 2019 в 20:14
поделиться

3 ответа

status="baz"
status=$(case $status in
  "foo") echo "bar" ;;
  "baz") echo "buh" ;;
  *) echo $status ;;
esac)
echo "status: $status"

выход

$ ./shell.sh
status: buh
4
ответ дан 3 December 2019 в 08:03
поделиться

Если вы уверены, что статус будет только одной строкой, вы можете сделать что-то вроде этого с помощью sed:

status=$(echo "$status" | sed -e 's:^foo$:bar:' -e 's:^baz$:buh:')

Вы также можете заставить что-то работать с помощью встроенной подстановки bash. Это почти работает (я не знаю никакого способа получить только точное соответствие):

status=${status/foo/bar}
status=${status/baz/buh}

Если ваша цель - просто быть более «функциональным» (а не делать ваш код более защищенным от опечаток ), вы могли бы сделать это:

status=$(
  case "$status" in
    ("foo") echo "bar" ;;
    ("baz") echo "buh" ;;
    (*) echo "$status" ;;
  esac)

Хотя, честно говоря, bash, вероятно, один из худших языков, на котором стоит пытаться работать. Он действительно был разработан с более императивным мышлением, о чем свидетельствует тот факт, что вы не можете легко сочинять выражения. Видите во втором фрагменте кода, как мне пришлось разбить его на два отдельных оператора? Если бы bash был функциональным, вы могли бы написать что-то вроде этого:

status=${{status/baz/buh}/foo/bar}

Но это не работает.

Я бы посоветовал использовать bash только для более простых сценариев, а для более сложных вещей использовать что-то вроде Python или Ruby. Они позволят вам писать более функциональный код без необходимости постоянно ломать голову над языком.

12
ответ дан 3 December 2019 в 08:03
поделиться

В Bash 4 есть ассоциативные массивы:

# setup
unset vals i
indices=(foo baz)
val=(bar buh)
declare -A vals             # associative
for index in ${indices[@]}
do
    vals[$index]=${val[i++]}
done

$ # demos
$ status="foo"
$ status=${vals:-$status}
$ echo $status
bar
$ status="not found"
$ status=${vals:-$status}
$ echo $status
not found
-1
ответ дан 3 December 2019 в 08:03
поделиться
Другие вопросы по тегам:

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