Как напечатать строки между одним и тем же шаблоном с несколькими вхождениями?

Кажется, мне удалось решить эту проблему - оказывается, помимо /etc/modprobe.d, есть еще /usr/lib/modprobe. d, и хотя я удалил файл черного списка nouveau программы установки nvidia из /etc/modprobe.d/, я не удалил файл в /usr/lib/modprobe.d/, поэтому nouveau не загружалась. Удаление этого файла означает, что теперь все работает.

Я обнаружил дополнительный конфигурационный файл, запустив

diff <(sudo lsinitrd /boot/initramfs-4.7.4-200.fc24.x86_64.img) <(sudo lsinitrd /boot/initramfs-4.7.2-201.fc24.x86_64.img) | less

и просматривая различия, пока не нашел что-то подозрительное. Там много шума (все драйверы ядра изменили путь), но, к счастью, это было довольно легко обнаружить.

3
17.11.2018, 04:22
4 ответа
start=3; # these can only be positive integers
 stop=4; # stop > start

perl -lne "// or print if /Pattern/ && ++\$a == $start ... // && ++\$a == $stop" data.in

Perl-решение использует оператор диапазона ... , где два операнда действуют как триггеры: => пока первый операнд ложен, ... возвращает ложный. Как только первый операнд становится истинным, ... возвращает истину. Он станет ложным только тогда, когда второй операнд станет истинным. Тонкость возникает из-за того, что операнд1 не оценивается, как только он становится истинным, и операнд2 не оценивается, пока операнд1 является ложным.

sed -nE "
   /Pattern/!d
   x
      s/\$/./
      /^[.]{$start}\$/!{x;d;}
   x

   n

   :loop
      p;n
      /Pattern/{
         x
            s/\$/./
            /^.{$stop}\$/q
         x
      }
   bloop
" data.in

Решение sed использует пространство хранения для подсчета количества просмотров шаблона. Мы продолжаем отклонять строки до тех пор, пока не будет обнаружено $start количество шаблонов. Как только приходит шаблон $start-th, мы запускаем цикл, который продолжает читать следующую строку, выводить ее и все время измерять, виден ли шаблон $stop-th. Однажды увидев, мы быстро уходим.

0
27.01.2020, 21:21

На основе этот ответ,

awk '/Pattern/{n+=1}; n % 2 == 1 && ! /Pattern/ {print > "output"((n-1)/2)}' input_file 

Объяснение

  • /Pattern/{n+=1}: при совпадении Pattern увеличивается n на 1.
  • n % 2 == 1 && ! /Шаблон/: выполните следующие действия только тогда, когда n нечетно, т.е. после каждого альтернативного шаблона. Кроме того, игнорируйте строки с Pattern.
  • {print > "output"((n+1)/2)}': если приведенное выше верно, то напечатайте эту строку в файл с именем outputx, где x равно ((n+1)/2), т.е. выход1, выход2, выход3
2
27.01.2020, 21:21

С sed:

sed -n '/Pattern/!d;:a
n;//! {w file1.txt
ba
};:b 
n;//! bb
:c
n;//q;w file2.txt
bc
' file

С POSIX sed Вы должны сделать 3 таких цикла для обоих совпадений и между ними, как вы не можете генерировать имена файлов из скрипта.

0
27.01.2020, 21:21

Альтернативный подход AWK

 $ awk -v start=3  '/Pattern/{n++;next};n==start;n==start+1{exit}' input.txt                                                     
Line 11
Line 12

$ awk -v start=2 '/Pattern/{n++;next};n==start;n==start+1{exit}' input.txt                                                      
Line 8
Line 9

Объяснение

Это работает довольно просто:

  • используя флаг -v мы определяем переменную, которую мы увеличиваем, если находим соответствующий шаблон и переходим к следующая строка (это /Pattern/{n++;next} часть кода)
  • в awk, если условие истинно, это автоматически сигнал для печати материала, следовательно, n==start можно просмотреть так же, как n==start{print}.
  • последний кодовый блок, в котором мы смотрим, достигли ли мы следующего шаблона, это n==start+1{exit}. Скажем, мы хотели напечатать строки между 4-м и 5-м вхождением шаблона. Это будет означать, что когдаn==4+1` код завершается

Если бы мы занимались гольфом, мы могли бы сделать это еще короче, просто изменив переменную start на что-то вроде -vs=1, что сокращает код следующим образом:

awk -v s=3  '/Pattern/{n++;next};n==s;n==s+1{exit}'

Предположения:

  • GNU awk
  • мы читаем между последовательными шаблонами, то есть между соответствием n и n+1

Обобщение подхода

Что, если мы хотим напечатать строки между шаблонами 2 и 4? Используя несколько трюков, использованных в предыдущем примере, мы можем сделать это так:

$ awk -v start=2 -v finish=4 '/Pattern/{n++;next};n==finish{exit};n>=start' input.txt                                           
Line 8
Line 9
Line 11
Line 12

Обратите внимание, что здесь мы определяем другую переменную,finish, чтобы знать, где остановиться. Таким образом, n==finish остановит печать строк. Обратите также внимание на то, что n==finish{exit} предшествует n>=start, что позволяет нам избежать повторного вывода той же строки, где мы должны выйти.

1
27.01.2020, 21:21

Теги

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