Рейтинг:7

BASH: Как я могу объединить две (или более) манипуляции со строками переменных за один шаг?

флаг tr

Можно ли объединить две или более функции обработки строк переменной в BASH (или любая другая стандартная команда Linux)?

скажем например у меня есть переменная $XDG_CURRENT_DESKTOP который держит строку Убунту: ГНОМ.
Теперь я могу получить вторую подстроку с помощью ${XDG_CURRENT_DESKTOP##*:}ГНОМ.
Я также могу получить строчную строку через ${XDG_CURRENT_DESKTOP,,}убунту:гном.

Но как я могу совместить обе функции ( гном) в одинпросто ✓ команда без использования перенаправления на сед, аук, grep или любой другой из них довольно тяжелый вес — команды и без дополнительного шага хранения буфера? например.:

локальный mybuffer="${XDG_CURRENT_DESKTOP##*:}"
эхо "${мойбуфер,,}"

Я хочу избежать такого «субскрипта» или конструкции вызова функции для достижения этой цели, и я уже пробовал любую комбинацию обоих упомянутых, но это кажется бесполезным.
Есть ли другой способ?
Или мне нужно обновить bash? (используя: GNU bash 4.3.11)
Или любая другая оболочка может сделать это?

флаг hr
`zsh` может сделать это с флагом расширения параметра `L`, например. `${(L)XDG_CURRENT_DESKTOP##*:}`
Jens avatar
флаг tr
@steeldriver: Ооо, здорово! _ЭТО_ именно то, что я искал! Время для `зш`. Большое спасибо! :))
terdon avatar
флаг cn
@steeldriver также может опубликовать это как ответ, поскольку ОП также запросил другие оболочки.
Jens avatar
флаг tr
@terdon: согласен
Рейтинг:4
флаг cn

Вы могли бы сделать это в бить если вы используете читать для чтения двух переменных:

$ эхо "$XDG_CURRENT_DESKTOP"
Убунту: ГНОМ
$ IFS=':' читать var1 var2 <<<"${XDG_CURRENT_DESKTOP@L}"
$ эхо "$var2"
гном

${переменная@L} конструкция возвращает значение $переменная преобразованы в нижний регистр. Затем, IFS=':' читать устанавливает разделитель полей ввода на : для читать команда, таким образом, глобальная IFS остается неизменной после выхода из команды, а затем читать var1 var2 разделит его вход на : и сохранить результат в двух переменных переменная1 и переменная2. Обратите внимание, что если у вас более одного : в той же строке ввода, переменная1 будет все до первого : и переменная2 все остальное. В заключение, <<< это "здесь строка", простой способ передать переменную в качестве входных данных для команды.

Jens avatar
флаг tr
Хороший обходной путь! Но, к сожалению, эта конструкция слишком длинная и, по-видимому, связана со многими фоновыми процессами _(— принцип KISS)_. Кстати, с этой версией bash я думаю, что могу принять комбинацию, аналогичную предложению zsh от @steeldriver выше. В любом случае 1+ за вдохновение!
terdon avatar
флаг cn
@Jens, это долго и громоздко писать, абсолютно. Zsh имеет тенденцию быть более элегантным с такими вещами. Но много фоновых процессов? Почему? Это все 100% встроенные инструменты bash, я не думаю, что будет много (каких-либо?) разветвлений.
Jens avatar
флаг tr
Хорошая точка зрения! Я просто пытаюсь реализовать что-то вроде _"универсальной директивы/константы"_, которая на самом деле не требует много кода и фоновой обработки.Тем временем я так или иначе пришел к выводу, что `zsh` может быть контрпродуктивным из-за того, что он, похоже, не получил широкого распространения. Так что это не имеет большого смысла.
terdon avatar
флаг cn
@Jens zsh становится все более и более популярным и является оболочкой по умолчанию в некоторых системах, отличных от Ubuntu (насколько я знаю, macOS, но, возможно, и в других), но да, вы не можете предположить, что она будет доступна. Но тогда вы также не можете предположить, что bash доступен :). Для настоящей переносимости вам нужно придерживаться базовой оболочки POSIX, такой как `sh` или `dash`. Мой ответ зависит от башизмов, переносимым способом будет подключение к переносимому внешнему инструменту, такому как `sed` или `perl`. Все это здесь не по теме, мы занимаемся только Ubuntu. Вы можете проверить [linux.se] на вопросы о переносимости.
Jens avatar
флаг tr
sh, dash, bash, zsh и т. д. ... слишком много вариантов ... Я думаю, что потерял из виду глобальный вид с этой деталью ;oP Должен признаться, я еще не рассматривал этот вопрос оболочки. Возможно, пока мне следует остаться с `bash`. С этой точки зрения ваш код выглядит намного лучше, чем больше я о нем думаю xD
Рейтинг:0
флаг ng

Вот скрипт bash5 (не bash4):

часть 2() {
   местный -n var=$1
   вар=${вар#*:}
}
ЖК () {
   местный -n var=$1
   вар=${вар,,}
}
фред = "убунту: гном"
часть 2 Фред
ЛК Фред
printf "%s\n" "$fred"

Вывод:

гном

Функции часть 2 и ЖК изменить переменную, имя которой им передано, без разветвления. В конце концов, исходная переменная (Фред) был изменен. Однако вам все еще нужна дополнительная переменная.

Альтернатива, которая должна работать на bash4, выглядит примерно так:

part2() { printf "%s" "${1#*:}"; }
lc() { printf "%s" "${1,,}"; }
фред = "убунту:GNOME"
printf "%s\n" "$(lc "$(part2 "$fred")")"

который не изменяет никакие переменные (он только манипулирует значениями), но создает дополнительные ответвления.

Jens avatar
флаг tr
Прежде всего: спасибо за ваши усилия. Результат в порядке. К вашему сведению: _весь_ ваш код на самом деле является Bash4 ;-).Я действительно ценю модульное программирование, но в данном случае я больше искал единый командный код или, альтернативно, однострочный код. Извините, но все равно большое спасибо.

Ответить или комментировать

Большинство людей не понимают, что склонность к познанию нового открывает путь к обучению и улучшает межличностные связи. В исследованиях Элисон, например, хотя люди могли точно вспомнить, сколько вопросов было задано в их разговорах, они не чувствовали интуитивно связи между вопросами и симпатиями. В четырех исследованиях, в которых участники сами участвовали в разговорах или читали стенограммы чужих разговоров, люди, как правило, не осознавали, что задаваемый вопрос повлияет — или повлиял — на уровень дружбы между собеседниками.