Начиная с первой задачи, выполнять изменение только для закрытых {}
:
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
, вам нужен обходной путь
Раньше я использовал решение на основе /etc/modprobe.d/
-, но обнаружил, что оно чрезвычайно сложно в настройке и чувствительно к обновлениям и другим изменениям конфигурации. Потом я нашел способ лучше.
Вы можете использовать правила udev для упорядочивания звуковых устройств, даже если они используют один и тот же драйвер. Требуемые правила будут выглядеть так:
# Make the HDMI audio the second sound device...
ACTION=="add", SUBSYSTEM=="sound", DRIVERS=="snd_hda_intel", KERNEL=="card*", KERNELS=="0000:00:01.1", ATTR{number}="1", ATTR{id}="HDMI"
#... and the analog audio chip the first one.
ACTION=="add", SUBSYSTEM=="sound", DRIVERS=="snd_hda_intel", KERNEL=="card*", KERNELS=="0000:00:14.2", ATTR{number}="0", ATTR{id}="Analog"
Если вы хотите, чтобы PulseAudio полностью игнорировал звук HDMI, добавьте запятую и ENV{PULSE_IGNORE}="1"
в конец первого правила udev.
Поместите эти правила, например. /etc/udev/rules.d/51-local-sound.rules
, затем обновите initramfs с помощью sudo update-initramfs -u
и перезагрузитесь. Теперь вы должны найти свои звуковые устройства ALSA, упорядоченные так, чтобы аналоговый аудиочип был устройством #0, а в списке aplay -l
они теперь должны называться «Аналоговый» и «HDMI», а не «Универсальный _». 1» и «Универсальный» соответственно.