удалить пустые блоки с вложенностью

En el siguiente script, la función mktimecrea una marca de tiempo de Unix basada en el primer y segundo campo del archivo que se puede comparar con la fecha de referencia de dateproporcionada en el argumento deawk:

awk -v startdate=$(date -d '5 days ago' +%s) '{d=$1 OFS $2; gsub("[-:]", " ", d); t=mktime(d)} t>startdate' file
2
25.05.2019, 17:59
1 ответ
$ sed -n -f script.sed file
abc {
a
}
xyz {
so
}

Где script.sedэто

1 {
    # 1st line, save it to the hold space
    # and skip to next line.
    h
    d
}

# Append all other lines to hold space
# with an embedded newline as delimiter.
H

$ {
    # Last line, swap in hold space
    # (which by now contains the whole document).
    x

    # Replace all empty "word {... }" sections
    # until there are no more such sections.
    # "word" may be a single word or multiple words
    # separated by whitespace.

    :again
    s/[[:alnum:][:space:]]*[[:space:]]*{[[:space:]]*}//g
    t again

    # Squeeze multiple newlines into single newlines.
    s/\(\n\)\1*/\1/g

    # Output.
    p
}

Шаблон [[:space:]]соответствует пробелам и символам новой строки (и некоторым другим -пробелам, подобным символам ).

Шаблон [[:alnum:][:space:]]*[[:space:]]*{[[:space:]]*}будет соответствовать одному из ваших разделов word {... }, где {... }пуст или содержит только символы пробела (пробелы, табуляции, новые строки и т. д. )и где wordможет быть одно слово или несколько слов, разделенных пробелом. Он также будет соответствовать «анонимному» пустому разделу, такому как{ }(без метки wordперед ним ).

Пустые секции удаляются в цикле (метка againв коде ). Команда tперейдет к данной метке, если самая последняя команда sсделала хотя бы одну замену. Если это так, теперь могут быть дополнительные пустые разделы для удаления, отсюда и цикл.

Для таких данных, как

a { b { c { d { e { } } } } }

этот цикл выполнит команду sпять раз, (в конечном итоге удалив все ).


Ваш sedскрипт:

/{$/{N;/{\n\s}$/d}

или, в полной форме,

/{$/ {
    N
    /{\n\s}$/d
}

никогда не сможет удалить разделы, содержащие пустые разделы, как в a { b { } }. Кроме того, похоже, игнорируется метка секции и возможность того, что секция может выглядеть как a { b { } abc c { d { } } }(, которая будет полностью удалена, если будет разделена на две строки, а не преобразована вa { abc }).

Кроме того, я не уверен, что соответствует \s, но похоже, что это совпадает с [[:space:]]с GNU sed. Стандарт sedтребует символа новой строки или ;в конце команд, поэтому скрипт должен иметь d;}в конце (в однострочной версии -).

4
27.01.2020, 21:58

Теги

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