Делать
sed ': loop; s / \ (\ [[^] [] * \) | \ ([^] [] * \] \) / \ 1, \ 2 /; t loop ' input_file
Что происходит?
: loop
это метка для зацикливания; Я воспользуюсь этим через минуту.s/\(\[[^][]*\)|\([^][]*\]\)/\1,\2/
заменяет тот,|
который появляется между[
и]
с запятой. Сломано:s/ \( \[ [^][] * \) | \( [^][] * \] \) / \1,\2 /
\(
…\)
Разграничивает группу поиска и замены. Учитывая[
...]
с|
между ними, это соответствует[
вверх до (но не включая) (последний) в|
качестве одной группы, и все после|
вверх по (включительно) в]
качестве второй группы.\[
соответствует буквальному[
.[^][]
соответствует любому символу, кроме[
или]
. Это ломается как[^] []
т.е. экземпляр[^ characters_to_not_match ]
*
- ноль или более символов, кроме[
или]
.\)
- конец группы; обсуждалось выше.|
это литерал|
(тот, который мы хотим заменить).- Вторая половина регулярного выражения почти такая же, как и первая половина: соответствует группе, состоящей из нуля или более символов, отличных от
[
или]
, за которыми следует символ]
. - Затем замените все это первой группой, запятой и второй группой. Поскольку все в соответствующей строке находится в одной из групп, за исключением
|
, это функционально заменяет\
на,
.
t loop
- тест / передача. Еслиs
команда нашла совпадение и произвела замену, вернитесь к метке и попробуйте снова (потому чтоs
команда заменяет только по одному|
за раз). Если он не нашел соответствия, завершите командный сценарий и перейдите к следующей строке.