Рейтинг:1

Переменные для построения шаблонов для использования с sed

флаг jp

Я написал функцию bash для печати разделов текста, заключенных между строками, соответствующими ## режим: орг. и ## # Конец организации в файле с пустой строкой между секциями. Перед ##, может быть любое количество пробелов.

Вот пример файла, из которого нужно извлечь информацию.

файл: test.sh

## режим: орг.
## * Использование оператора case
## # Конец организации
case $arg в
 («В»)
   эхо "Автор"
   ;;
 (*)
   ## режим: орг.
   ## ** Режим автоматического сообщения об ошибках (SERM) в getopts
   ## *** Обнаруживает предупреждения без вывода встроенных сообщений.
   ## *** Включается двоеточием {:} в качестве первого символа в сокращении.
   ## # Конец организации
   сломать
   ;;
эсак

Желаемый результат будет

Код:

* Использование оператора case

** Режим тихих отчетов об ошибках (SERM) в getopts
*** Обнаруживает предупреждения без печати встроенных сообщений.
*** Включается двоеточием {:} в качестве первого символа в сокращении.

Вот функция, которую я использую

захват-орг ()
{
  локальный файл = "$1"

  local begsec="## режим: org"
  local endsec="## # Конец организации"

  sed -n "/^[[:space:]]*${begsec}$/,/^[[:space:]]*${endsec}$/s/ *//p'" "$efile" |
   sed 's/^'"${begsec}"'$/\n'"${begsec}"'/' |
   sed '/^'"${begsec}"'$/d' | sed '/^'"${endsec}"'$/d' | вырезать -с 3-
}

Я хотел бы упростить функцию, используя переменные для построения шаблонов. Но мне нужна помощь для компиляции команд, чтобы мне не приходилось вызывать сед так много раз.

Возможно, используя аук будет лучшей стратегией.

захват-орг ()
{
  локальный файл = "$1"

  local begsec='^[[:space:]]*## режим: org$'
  local endsec='^[[:space:]]*## # Конец org$'

  sed -n "/${begsec}/,/${endsec}/s/ *//p" "$efile" |
   sed 's/^## # Конец организации$/## # Конец организации\n/' |
   sed '/^## режим: org$/d' | sed '/^## # Конец org$/d' | вырезать -с 3-
}
Рейтинг:1
флаг cn

Я бы действительно использовал что-то более сложное для этого. Как авк:

$ awk -v start="$begsec" -v end="$endsec" \
    '{ 
        если ($ 0 ~ начало) {хочу = 1; следующий} 
        если ($ 0 ~ конец) {хочу = 0; Распечатать ""; следующий} 
        gsub(/\s*#+\s*/,""); 
     } хочу' файл
* Использование оператора case

** Режим тихих отчетов об ошибках (SERM) в getopts
*** Обнаруживает предупреждения без печати встроенных сообщений.
*** Включается двоеточием {:} в качестве первого символа в сокращении.

Или, используя вашу последнюю функцию в качестве шаблона:

захват-запись ()
{

  local begsec='## режим: org'
  local endsec='## # Конец организации'

  awk -v start="$begsec" -v end="$endsec" \
    '{ 
        если ($ 0 ~ начало) {хочу = 1; следующий} 
        если ($ 0 ~ конец) {хочу = 0; Распечатать ""; следующий} 
        gsub(/\s*#+\s*/,""); 
     } хочу' "$1"
}

Одно предостережение, которое может быть важным, заключается в том, что это не требует, чтобы $begsec и $endsec быть единственными вещами в строке, кроме начальных пробелов, как в вашем подходе, он просто ищет их в любом месте строки. Я предполагаю, что это не очень важно, учитывая то, что вы ищете, но если это так, вы можете использовать это вместо этого, которое удалит пробелы в начале и конце строки перед сопоставлением:

захват-запись ()
{

  local begsec='## режим: org'
  local endsec='## # Конец организации'

    awk -v start="$begsec" -v end="$endsec" \
    '{ 
        sub(/^[[:space:]]*/,"");
        sub(/[[:space:]]*$/,"");
        если($0==начало){хочу=1; следующий} 
        если($0==конец){хочу=0; Распечатать ""; следующий} 
        gsub(/\s*#+\s*/,""); 
     } хочу' "$1"
}
флаг jp
Он печатает другие части файла, предшествующие первой совпавшей строке.
флаг jp
Мне нужно, чтобы они были единственными элементами в строке, кроме начальных пробелов, потому что они будут выбраны, если я запущу команды в том же файле (выбрав `local begsec='## mode: org'` и `local endsec ='## # Конец организации'`).
terdon avatar
флаг cn
@Fatipati см. обновленный ответ для версии, которая работает только в строках, где начальная и конечная секунды представляют собой всю строку, за исключением начального и конечного пробелов. Если это не работает должным образом, пожалуйста, покажите мне файл, в котором это не работает, чтобы я мог понять, почему.
Рейтинг:0
флаг cn

Эта однострочная команда в вашем скрипте может выполнить эту работу:

awk '/## mode/{flag=1;next} /## # End/{flag=0} flag' extract.txt | тр -д /#/ | awk '$1=$1'

* Использование оператора case
** Режим тихих отчетов об ошибках (SERM) в getopts
*** Обнаруживает предупреждения без печати встроенных сообщений.
*** Включается двоеточием {:} в качестве первого символа в сокращении.

Второй awk просто удаляет начальные пробелы.

флаг jp
Как уже упоминалось, я печатаю больше строк, чем между частями «начало» и «конец». Это потому, что я передаю тот же файл, в котором у меня есть код и, следовательно, функция `capture-org`.
флаг jp
Мне нужно точно сопоставить шаблоны `^[[:space:]]*## mode: org$` и `^[[:space:]]*## # End of org$`.

Ответить или комментировать

Большинство людей не понимают, что склонность к познанию нового открывает путь к обучению и улучшает межличностные связи. В исследованиях Элисон, например, хотя люди могли точно вспомнить, сколько вопросов было задано в их разговорах, они не чувствовали интуитивно связи между вопросами и симпатиями. В четырех исследованиях, в которых участники сами участвовали в разговорах или читали стенограммы чужих разговоров, люди, как правило, не осознавали, что задаваемый вопрос повлияет — или повлиял — на уровень дружбы между собеседниками.