«пароль» и «интерактивная клавиатура» - это два разных типа аутентификации; хозяин предлагает позднее. Поэтому вам нужно использовать это в своем предпочтительном списке аутентификации:
ssh -o PreferredAuthentications=keyboard-interactive …
Начиная с первой задачи, выполнять изменение только для закрытых {}
:
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
, вам нужен обходной путь
Используя 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
, чтобы сделать его более применимым.