Как правильно заключать в кавычки расширения вложенных параметров?

Сsed:

sed 's/<\([0-9]*\)>/_\1/g'

Выполнение этого на примере в вопросе дает

_1 to _1
_21 to _21

Образец <\([0-9]*\)>соответствует любому количеству цифр внутри <...>. Текст замены заменяет этот бит ввода <...>цифрами (, если есть какие-либо )с префиксом _.


В Ви:

:%s/<\([0-9]*\)>/_\1/g

Это эквивалентно решению sedпо очевидным историческим причинам.


Если у вас есть строка <21>в переменной оболочки varв Bash:

printf '%s\n' "_${var//[<>]/}"

Будет напечатано _21с использованием подстановки переменных ${parameter//pattern/string}.


С tr. Примечание :Это дает видимость работы с очень ограниченным набором входных данных. Он слепо заменяет <на _и удаляет >, не обращая внимания на то, где они встречаются :

.
tr '<' '_' <file.in | tr -d '>'

Это скорее шуточное решение, чем серьезное, но будет работать , если только <и >, встречающиеся во входных данных, содержат цифры в -между ними.

2
11.12.2019, 05:00
2 ответа

В обоих случаях вам обычно нужен первый способ. Когда строка справа от ${var#*a}не заключена в кавычки, она интерпретируется/расширяется как шаблон. В этом примере удаление начального текста до первой буквы a. Если указать :${var#"*a"}, расширение удалит литерал *a. Это может быть проблемой, если в:

"${filename%."$filename_ext"}"

"$filename_ext"может содержать символы шаблона. Точно так же, если $varв "${var#"${var%%[![:space:]]*}"}"может содержать символы шаблона (*?[ )и вы не хотите, чтобы они интерпретировались как шаблон, тогда укажите расширение как:

"${var#"${var%%[![:space:]]*}"}"

Обратите внимание, что правая часть присваивания переменной считается заключенной в кавычки и не нуждается в (, но не причиняет вреда )кавычки, эти две также верны:

      var=${var#"${var%%[![:space:]]*}"}
strip_ext=${filename%."$filename_ext"}
1
27.01.2020, 22:02

Кажется, это зависит от того, как вы хотите интерпретировать правую -часть разложения. Как шаблон или как литеральная строка.

Здесь *без кавычек является шаблоном и съедает всю строку. Цитируемый просто удаляет буквальную звездочку:

var='foo*'
echo ":${var%%*}:"                 # this prints ::
echo ":${var%%"*"}:"               # this prints :foo:

То же самое, если пропустить шаблон через переменную:

var='foo*'
pat='*'
echo ":${var%%$pat}:"              # this prints ::
echo ":${var%%"$pat"}:"            # this prints :foo:

Или с другим расширением параметра справа:

var='foo*'
pat='x*x'
echo ":${var%%${pat//x}}:"         # this prints ::
echo ":${var%%"${pat//x}"}:"       # this prints :foo:

(${pat//x}снова дает просто *.)

Я получаю такое же поведение со всеми оболочками POSIX -, которые я пробовал (Bash, ksh, yash ). Zsh, конечно, отличается, все расширения параметров с правой стороны действуют так, как будто они там указаны в кавычках, как и в отношении проблем разделения слов -.Я полагаю, что есть какой-то оператор, который можно использовать в расширении, чтобы изменить это.

3
27.01.2020, 22:02

Теги

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