Замените шаблон перед вторым шаблоном - сохраните строку между двумя

«пароль» и «интерактивная клавиатура» - это два разных типа аутентификации; хозяин предлагает позднее. Поэтому вам нужно использовать это в своем предпочтительном списке аутентификации:

ssh -o PreferredAuthentications=keyboard-interactive …
2
06.05.2017, 00:44
2 ответа

Начиная с первой задачи, выполнять изменение только для закрытых {}:

printf '%s' '{$aaa} \\{$bbb} \{$ccc}  {$ddd' | sed 's/{$\([^}]*\)}/${\1}/g'

Это все после {$ до закрывающий } помещается в \(\), поэтому мы можем ссылаться на него в строке замены как \1. Вывод:

${aaa} \\${bbb} \${ccc}  {$ddd

Теперь об экранировании обратной косой черты. Ваше решение работает для \{$aaa} (не трогать) и \\{$aaa} (заменить), но как насчет \\\{$aaa }? Он выполнит изменение, которое, вероятно, нежелательно.

Поэтому я предлагаю сначала избавиться от всех двойных обратных косых черт. Мы заменяем их комбинацией символов, которая не может быть частью строки, например #1, и меняем ее обратно в конце. Таким образом, мы можем сосредоточиться только на одной обратной косой черте:

printf '%s' '{$aaa} \\{$bbb} \{$ccc} \\\{$eee} {$ddd' | sed 's/\\\\/#1/g;s/{$\([^}]*\)}/${\1}/g;s/#1/\\\\/g'

И, наконец, мы можем изменить \{ на #2 и заменить его в конце, чтобы он не мешался. :

printf '%s' '{$aaa} \\{$bbb} \{$ccc} \\\{$eee} {$ddd' | sed 's/\\\\/#1/g;s/\\{/#2/g;s/{$\([^}]*\)}/${\1}/g;s/#2/\\{/g;s/#1/\\\\/g'

Результат: ${aaa} \\${bbb} \{$ccc} \\\{$eee} {$ddd

И это будет работать для любого количества обратных косых черт.

Но если нет такого символа, как #, вы можете свободно использовать? Вы можете использовать новую строку, потому что новая строка не может быть частью строки. Поскольку вы, похоже, используете GNU sed, вы можете сделать

printf '%s' '{$aaa} \\{$bbb} \{$ccc} \\\{$eee} {$ddd' | sed 's/\\\\/\n1/g;s/\\{/\n2/g;s/{$\([^}]*\)}/${\1}/g;s/\n2/\\{/g;s/\n1/\\\\/g'

Если это должно работать на POSIX sed, вам нужен обходной путь

1
27.01.2020, 22:10

Используя POSIX sed, вы можете выполнить свою задачу следующим образом:

sed -e '
   # case for {$var}
   s/ \(\(\\\\\)\{0,\}\){\$\([^ }]*\)}/ \1${\3}/g
   s/^\(\(\\\\\)\{0,\}\){\$\([^ }]*\)}/\1${\3}/

   # case for ($var)
   s/ \(\(\\\\\)\{0,\}\)(\$\([^ )]*\))/ \1$(\3)/g
   s/^\(\(\\\\\)\{0,\}\)(\$\([^ )]*\))/\1$(\3)/
' input_file

Предполагая, что пробелы являются единственными пробелами в файле.Конечно, мы можем справиться с TAB и оставить это как упражнение для OP. С расширениями, доступными в GNU sed, мы можем еще больше упростить описанное выше, но я хотел предоставить решение POSIX, чтобы сделать его более применимым.

1
27.01.2020, 22:10

Теги

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