Я знаю, что это немного поздно, но вы можете использовать сочетания клавиш, которые будут привязываться так, как вы хотите, с двумя дисплеями.
Сочетания клавиш можно найти, выполнив поиск «клавиатура» в меню, перейдя на вкладку сочетаний клавиш, а затем в разделах «Windows» и «Мозаика и привязка».
Удачи.
В echo "X${xxx%% }X"
шаблон представляет собой один пробел:. Самая длинная совпадающая часть для этого — это :один пробел. Самая короткая совпадающая часть также представляет собой :один пробел.
Для чего-то большего вам понадобится оператор подстановки *
. Но это будет соответствовать чему угодно, удалив -Wall
. Подстановка Bash не поддерживает прямой эквивалент регулярного выражения a*
. Вам понадобится расширенное подстановочное значение:
$ shopt -s extglob
$ echo "X${xxx%%+( )}X"
X-O -WallX
Использовать удаление префикса в удалении суффикса:
$ xxx="-O -Wall "
$ echo "X${xxx%"${xxx##*[! ]}"}X"
X-O -WallX
$ bash -c 'xxx="-O -Wall* "; echo "X${xxx%%"${xxx##*[! *]}"}X"'
X-O -WallX
$ bash -c 'xxx="-O -Wall* "; echo "X${xxx%%${xxx##*[! *]}}X"'
XX
Надуманный пример, но если внутреннее расширение не указано в кавычках, звездочка, которую оно включает, будет рассматриваться внешним расширением как образец оболочки. В кавычках оно становится буквально звездочкой.
Наблюдаемое вами поведение не является ошибкой, это просто то, как работают простые шаблоны оболочки:
${xxx%% }
${xxx%% *}
-Wall
${xxx% }
${xxx% *}
${xxx%% \*}
\*
— звездочка, экранированная обратной косой чертой, и будет интерпретироваться как буквальная звездочка Это можно сделать с помощью сопоставления регулярных выражений следующим образом:
~> xxx="-O -Wall "
~> echo "X${xxx}X"
X-O -Wall X
~> [[ "$xxx" =~ (\ +$) ]]; echo $?,"X${BASH_REMATCH[0]}X"
0,X X
~> echo "X${xxx%%${BASH_REMATCH[0]}}X"
X-O -WallX
~/src/Perl> xxx="-O -Wall"
~/src/Perl> echo "X${xxx}X"
X-O -WallX
~/src/Perl> [[ "$xxx" =~ (\ +$) ]]; echo $?,"X${BASH_REMATCH[0]}X"
1,XX
~/src/Perl> echo "X${xxx%%${BASH_REMATCH[0]}}X"
X-O -WallX
read
также может работать (, предполагая, что IFS
содержит «пробел»):
xxx="-O -Wall "
read -r xxx <<EOF
$xxx
EOF
echo "X${xxx}X"
Выход:
X-O -WallX
read
разбивает ввод на поля в соответствии сIFS
IFS
по умолчанию используется пробел/табуляция/новая строка, поэтому будут удалены все начальные и конечные пробелы bash
можно использоватьread -d ''
)Простое расширение параметра весьма ограничено шаблонами, которые оно может сопоставлять и удалять. Чтобы удалить несколько (повторяющихся )символов, образующих конец строки, обычное решение состоит в том, чтобы сначала удалить все, что не рассматриваемый символ${xxx##*[! ]}
(все конечные пробелы ). Затем, в качестве второго шага, удаление всех результатов этого расширения (всех конечных пробелов )с конца даст вам то, что вы хотите (удалить конечные пробелы ).
$ xxx="-O -Wall "
$ echo "<${xxx%"${xxx##*[! ]}"}>"
<-O -Wall>
В качестве альтернативы в bash вы можете использовать расширенное подстановочное значение:
$ shopt -s extglob
$ echo "<${xxx%%+( )}>"
<-O -Wall>
Или, в качестве альтернативы более высокого уровня, вы можете сопоставить то, что хотите, с регулярным выражением:
$ regex='(.*[^ ]) +$';
$ [[ $xxx =~ $regex ]] && echo "<${BASH_REMATCH[1]}>" || echo "<$xxx>"
<-O -Wall>
Или,как сценарий:
#!/bin/bash
xxx=${1:-"-O -Wall "}
regex='(.*[^ ]) +$'
if [[ $xxx =~ $regex ]] # if there are trailing spaces
then
echo "<${BASH_REMATCH[1]}>" # Print the string without spaces
else
echo "<$xxx>" # if there are no trailing spaces.
fi