Ваш подход добавления линий для блока в пространство образца возможен; мы просто должны сделать это только для блока, т.е. е. от строки, заканчивающейся [
или {
до строки, начинающейся с ]
или }
:
sed '/[[{]$/{:a;N;/\n[]}]/!ba;s/\n\s*//g}' test.yml
Отступы как для внутреннего ({
, [
), так и для внешнего (}
, ]
) не определены и могут фактически отличаться.
Из вашей скрипки я понимаю, что отступ закрывающего ]
или }
равен отступу строки с открывающим [
или {
. Основываясь на этом, это скрипт awk
, который работает аналогично скрипту sed
, но дополнительно обрабатывает отступы путем поиска одинаково отступающего конца блока:
#!/usr/bin/awk -f
/[[{]$/ { match($0, /( *)/, space) # space[1] contains the indentation
do { printf "%s", $0; getline; t = $0; sub(/ */, "") }
while (!match(t, "^"space[1]"[]}]")) # search block end
}
{ print } # print simple line as well as last line of block
Я получаю эту ошибку при запуске вашего скрипта ./awk.sh: line 2: syntax error at or near ,
У вас есть версия awk
, которая не поддерживает третий аргумент match()
. Здесь вы можете заменить match($0, /( *)/, space)
на match($0, /( *)/); space[1] = substr($0, RSTART, RLENGTH)
.
если закрывающая фигурная / квадратная скобка не начинается с новой строки, ваш скрипт выполняется вечно и не завершается.
Если квадратные скобки размещены не так регулярно, как предполагает приведенный выше сценарий, требуется другой подход. Следующий скрипт просто считает уровень вложенности скобок, пока он не достигнет нуля; кроме того, он проверяет конец файла, чтобы он не работал вечно, если файл содержит незамкнутый блок.
/[[{]$/ { level = 1 # bracket nesting level
do { printf "%s", $0; if (!getline) exit 1; sub(/ */, "")
level += gsub(/[[{]/, "&") - gsub(/[]}]/, "&")
} while (level) # search block end
}
{ print } # print simple line as well as last line of block