Использование переменной bash с escape-символом в awk для извлечения строк из файла

Я пишу сценарий bash (просто обучение bash), чтобы извлечь некоторые строки из файла на основе двух шаблонов. Первый шаблон – это просто предложение, заканчивающееся в двоеточие. Второй образец – это * повторный N (в данном случае 58) раз.

Пример файла:

 lines I don not want lines I don not want lines I don not want A sentence here: ******************************************************** lines I want lines I want lines I want ********************************************************** lines I don not want lines I don not want lines I don not want 

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

 A sentence here: ******************************************************** lines I want lines I want lines I want ********************************************************** 

Я могу заставить скрипт работать, если я явно напечатаю A sentence here и \* 58 раз в вызове awk, но чистоту и удобочитаемость я бы предпочел сделать что-то вроде ниже:

 pat1="A sentence here" pat2=`printf -- '\*%.s' {1..58} ; echo` pat2=${pat2//\\/\\\\} awk -v pat1="${pat1}" -v pat2="${pat2}" '/{pat1}/ {p=1}; p; /{pat2}/ {p=0}' $1 

Если первой позиционной переменной является входной файл. Вышеприведенный код ничего не возвращает. Сначала я попробовал его без замены на pat2 , но получил предупреждение:

 awk: warning: escape sequence `\*' treated as plain `*' 

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

Редактировать:

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

One Solution collect form web for “Использование переменной bash с escape-символом в awk для извлечения строк из файла”

Несколько вариантов здесь:

  • pat1, pat2 обрабатываются как регулярные выражения:

     pat1="A sentence here" pat2='\*{58}' export pat1 pat2 awk '$0 ~ ENVIRON["pat1"], $0 ~ ENVIRON["pat2"]' 

    Обратите внимание, что mawk и версии gawk до 4.0.0 не поддерживают {} расширенный оператор регулярных выражений. Для старых версий gawk вы можете передать переменную среды POSIXLY_CORRECT чтобы узнать ее.

    Здесь, используя start-condition, end-condition [{action}] , вы можете сделать то же самое с подходом p флага.

  • pat1, pat2 обрабатываются как фиксированные строки:

     pat1="A sentence here" pat2=$(printf '*%.0s' {1..58}) export pat1 pat2 awk 'index($0, ENVIRON["pat1"]), index($0, ENVIRON["pat2"])' 

    Здесь index() ищет иглу (переменное содержимое) в любом месте стога сена (текущая запись (строка)), но вы также можете выполнить простое сравнение по полной схеме:

     awk '"" $0 == ENVIRON["pat1"], "" $0 == ENVIRON["pat2"]' 

    ( "" – это принудительное сравнение строк даже в случаях, когда как $0 и ENVIRON["patx"] являются численными).

Избегайте использования -v для передачи данных, которые могут содержать символы обратной косой черты, поскольку awk выполняет некоторую C-escape-последовательность ( \n , \b , \\ …) на них, поэтому вам нужно будет избежать обратных косых черт. То же самое касается переменных, передаваемых как awk '...code...' awkvar="$shellvar" . ENVIRON этого используйте ENVIRON или ARGV .

Дополнительную информацию см. В этом ответе на соответствующий вопрос .

  • Использование ARGV для ввода пользовательского ввода в сценарий Awk
  • Сценарий оболочки и добавление больших значений в проблему с ограниченным файлом
  • awk - читать программу И ввод со стандартного ввода?
  • Как просмотреть файлы, содержащие пробелы в имени файла?
  • Извлечь начальное и конечное положение общего идентификатора
  • сравнить два файла, получить идентичный список
  • Могу ли я получить доступ к массиву, созданному в одном скрипте awk в последующем скрипте awk?
  • Греп на одной линии
  • сравнение времени, заданного пользователем для времени файла журнала
  • Как использовать sed или awk для извлечения определенных строк в файле
  • awk, вырезать символы из подстроки
  • Linux и Unix - лучшая ОС в мире.