Как к grep строка с неизвестным количеством ее строк с отступом

Я предполагаю, что Вы пытаетесь сделать это в оболочке или подобный (еще, Вы просто пользовались бы этими X библиотеками непосредственно). Если так, можно найти xinput --test «device-name» намного легче проанализировать.

К сожалению, это действительно не пишущая сценарий оболочки товарищеская встреча. Но можно заставить его работать с stdbuf. Это работает, пока Вы не уничтожаете его, но Ваш сценарий оболочки мог передать его по каналу к read.

Так, можно сделать что-то вроде этого:

stty -echo
stdbuf -oL xinput test 'AT Translated Set 2 keyboard' \
    | perl -nE 'BEGIN {$| = 1} m/^key press\s+(\d+)/ and say $1' \
    | for key in q w e r t y; do
         echo -n "Please press $key: "
         read -r keycode
         echo "key $key = $keycode"
    done
stty echo

Необходимо будет использовать корректное название клавиатуры вместо "В Переведенном Наборе 2 клавиатуры". Можно найти его с xinput list:

anthony@Zia:~$ xinput list
⎡ Virtual core pointer                          id=2    [master pointer  (3)]
⎜   ↳ Virtual core XTEST pointer                id=4    [slave  pointer  (2)]
⎜   ↳ Logitech USB-PS/2 Optical Mouse           id=8    [slave  pointer  (2)]
⎣ Virtual core keyboard                         id=3    [master keyboard (2)]
    ↳ Virtual core XTEST keyboard               id=5    [slave  keyboard (3)]
    ↳ Power Button                              id=6    [slave  keyboard (3)]
    ↳ Power Button                              id=7    [slave  keyboard (3)]
    ↳ AT Translated Set 2 keyboard              id=9    [slave  keyboard (3)]

К сожалению, необходимо использовать определенное устройство — Вы не можете использовать базовую клавиатуру.

(Кроме того, необходимо будет найти способ уничтожить xinput в вышеупомянутом или просто содержание сами для удара Ctrl-C при вводе всех ключей. И Вы, вероятно, захотите перечислить больше ключей, чем стандартное расположение букв на клавиатуре.)

5
05.10.2015, 22:20
6 ответов

Если вы хотите вывести матч Regexp и все строки с отступом, которые сразу после совпадения:

command | perl -ne '/^( *)/; $i = length $1; $j && $i >= $j and print, next; $j = 0; /REGEXP/ and $j = $i + 1, print'

замена Regexp вашим регулярным выражением.

Например,

$ perl -ne '/^( *)/; $i = length $1; $j && $i >= $j and print, next; $j = 0; /a/ and $j = $i + 1, print' <<EOF
a
b
  c
  a
    b
    a
    c
      b
    d
  e
    b
  a
    c
e
EOF

выходы:

a
  a
    b
    a
    c
      b
    d
  a
    c
1
27.01.2020, 20:37

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

Это сказано, что я предпочел бы использовать awk в вашем первом примере:

lspci -vq | awk 'BEGIN{RS="\n\n";IGNORECASE=1} /wireless/'

и PCREGREP в секунду:

iwlist wlan0 scan | pcregrep -iMo 'cell 13(.|\n)*(?=cell 14)'
0
27.01.2020, 20:37

Это будет совпадать с ячейки 13 к следующему случаю ячейки

sudo iwlist wlan0 scan | awk '/Cell/{p=0} /Cell 13/{p=1} p'

Три команды в awk awk awk awk :

  1. / Cell / {p = 0} - Если слово «ячейка» существует в строке, прекратите печать (если мы печатаем ранее
  2. / Ячейка 13 / {p = 1} - если строка «ячейка 13» существует в строке, начальная печать
  3. p - распечатайте всю строку (которая подразумевается из-за NO {. ..} Часть) Если p! = 0
0
27.01.2020, 20:37

Общим решением является использование sed с адресом в диапазоне . Все вы должны каким-то образом указать строки, с которых начинать и останавливаться. Это может быть keyword(s), indent level, empty line или что-то еще:

  • keyword

    iwlist wlan0 scan | sed -n '/Cell 04/{:1;p;n;/Cell/! b1}'

  • уровень отступа

    iwlist wlan0 scan | sed -n '/Cell 04/{:1;p;n;/^\s\{1,18}\S/!b1}'

  • пустая строка

    lspci -vq | sed -n '/[Ww]ireless/{:1;p;n;/^$/! b1}'

0
27.01.2020, 20:37

Решение, основанное на соответствующих заголовках разделов

Для печати текста, начинающегося с ячейки 13, но останавливающегося перед ячейкой 14, используйте ячейку :

sudo iwlist wlan0 scan | awk '/Cell 13/{f=1} /^ *Cell 14/{f=0} f'

Решение, основанное на отслеживании уровня отступов

В результате будут выведены все строки, начинающиеся с той, которая содержит ячейку 13 и продолжающиеся со всеми следующими строками, которые имеют уровень отступов больше :

sudo iwlist wlan0 scan | awk '/Cell 13/ && !f{f=1;x=$0;sub(/[^ ].*/,"",x);x=x" ";print;next} f {if (substr($0,1,length(x))==x)print; else f=0}'

Как это работает:

В коде используются две переменные. f - это флаг, который равен 1, если мы находимся в секции, которую хотим распечатать, и 0 в противном случае. Строка x установлена на один пробел больше, чем отступ в начале секции, которую мы хотим распечатать.

  • /Ячейка 13/ && !f{f=1;x=$0;sub(/[^ ].*/,",x);x=x" ";print;next}

    Это ищет строки, которые содержат Ячейка 13 (или что-то еще, что означало бы начало раздела. Если строка совпадает с этим и если мы еще не находимся в этом разделе, то:

    1. f устанавливается равным 1.

    2. Строка x устанавливается в отступ, который начинает строку.

    3. Эта строка распечатана.

    4. Остальные команды пропускаются, и мы переходим к следующей строке .

  • f {if (substr($0,1,length(x))==x)print; else f=0}

    Если мы находимся внутри распечатываемого участка (f не равен нулю), то проверяем уровень отступов. Если отступ не менее x, то выведите эту строку. В противном случае, установив f=0, мы получим сигнал о том, что мы достигли конца отступа.

5
27.01.2020, 20:37

Вот пример того, как это можно сделать с sed :

srch_rng(){                      
        set     '[:blank:]' "$1" '\
';      sed -n " /^\(.*\n\)*[$1]*$2/,\$!{N
                s/^\(\([$1]*\)[$1]*[^$1].*\n\)\(\2[^$1]\)/\3/
                        s/^/$3/;D           
        };       /./!p;//!d;H;x
                 /^\n[$1]*/!h;s///p;t       
                s/\([$1]*\).*\n\1//;/^[$1]/p
                 //!q;x;s/\n.*//;h"
}

Это работает с обеими сторонами диапазона - до sed совпадает с шаблоном, указанным в качестве его первого аргумента относительно его stdin , который он будет сохранять в памяти до каждого встречного отступа верхнего уровня. После сопоставления своего первого аргумента он не сохраняет ничего, кроме отступа.

Перед тем, как найти соответствие, он работает в цикле вытягивания строки N ext, пытаясь s /// убрать все пространство шаблонов, если последняя строка вытянута in открывается с количеством пробелов, меньшим или равным тому же количеству пробелов, что и первая строка в его буфере, за которой сразу следует непустой символ, затем возвращается цикл, чтобы выяснить, соответствует ли она самой последней строке или должна попробуй еще раз.

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

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

Так, например, если я просто введу srch_rng Cell , он будет печатать из строки Cell 13 до следующей Cell . Он также сделает это, если я укажу ESSID в качестве первого аргумента, но если я это сделаю:

srch_rng '.*selma'

... он напечатает ...

Cell 14 - Address: 90:F6:52:90:C2:2F
                    Channel:6
                    Frequency:2.437 GHz (Channel 6)
                    Quality=21/70  Signal level=-89 dBm  
                    Encryption key:on
                    ESSID:"selma"
          Bit Rates:1 Mb/s; 2 Mb/s; 5.5 Mb/s; 11 Mb/s; 6 Mb/s
                    9 Mb/s; 12 Mb/s; 18 Mb/s%                

Требуется . * потому что по умолчанию он соответствует только первым непустым символам в строке. И, как вы можете видеть, для каждой печатаемой строки он удаляет только начальные пробелы, которые он сохранил в буфере, из каждой - что помещает первую строку, напечатанную в крайнем левом углу, а все остальные с равномерным отступом под ней.

1
27.01.2020, 20:37

Теги

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