Как просто вернуть два числа после сопоставления с регулярным выражением с помощью grep или sed?

Как просто вернуть два числа после сопоставления с регулярным выражением с помощью grep или sed?

Я пишу скрипт оболочки для запуска при запуске, который отключает мой отслеживающий nub, который барахлит. Я начинаю с xinput list, который я передаю по конвейеру, grep Stickкоторый мне нужно перенаправить на что-то вроде этого, grep id=что дает мне два числа, обычно 11. числа находятся где-то от 1 до 18, насколько я могу судить, но мне нужно написать что-то вроде foo=xinput list | grep Stick | grep id=и устанавливает foo в 11. вот пример списка xinput:

⎡ Virtual core pointer                      id=2    [master pointer  (3)]
⎜   ↳ Virtual core XTEST pointer                id=4    [slave  pointer  (2)]
⎜   ↳ AlpsPS/2 ALPS DualPoint TouchPad          id=10   [slave  pointer  (2)]
⎜   ↳ AlpsPS/2 ALPS DualPoint Stick             id=11   [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)]
↳ Video Bus                                 id=7    [slave  keyboard (3)]
↳ Power Button                              id=8    [slave  keyboard (3)]
↳ AT Translated Set 2 keyboard              id=9    [slave  keyboard (3)]
↳ Toshiba input device                      id=12   [slave  keyboard (3)]
↳ TOSHIBA Web Camera - FHD                  id=13   [slave  keyboard (3)]

Мне нужно получить число сразу после id= в строке Stick, 11.

решение1

Короче говоря, вот команда, которая вам нужна:

foo="$(xinput list | grep -F 'Stick' | grep -Po '(?<=id=)\d\d?')"

Далее следует более подробное объяснение.


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

grep -Po '(?<=id=)\d\d?'

Это будет соответствовать подстрокам, которые начинаются с id=и за которыми следуют одна или две цифры, но вернет только цифры, а не id=префикс.

Вот как это можно проверить:

echo "id=11" | grep -Po '(?<=id=)\d\d?'

Это производит 11как его выход. Применение этого к вашему фрагменту кода дает следующее:

foo="$(xinput list | grep -F 'Stick' | grep -Po '(?<=id=)\d\d?')"

В качестве второго теста предположим, что мы поместили ваш пример данных в файл data.txt:

# data.txt
⎡ Virtual core pointer                      id=2    [master pointer  (3)]
⎜   ↳ Virtual core XTEST pointer                id=4    [slave  pointer  (2)]
⎜   ↳ AlpsPS/2 ALPS DualPoint TouchPad          id=10   [slave  pointer  (2)]
⎜   ↳ AlpsPS/2 ALPS DualPoint Stick             id=11   [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)]
↳ Video Bus                                 id=7    [slave  keyboard (3)]
↳ Power Button                              id=8    [slave  keyboard (3)]
↳ AT Translated Set 2 keyboard              id=9    [slave  keyboard (3)]
↳ Toshiba input device                      id=12   [slave  keyboard (3)]
↳ TOSHIBA Web Camera - FHD                  id=13   [slave  keyboard (3)]

Затем выполните следующую команду:

cat data.txt | grep -F 'Stick' | grep -Po '(?<=id=)\d\d?'

Это производит 11его на выходе.

решение2

Укажите AlpsPS/2 ALPS DualPoint Stickдля xinput

Указав имя устройства, если оно известно, xinputбудет выбрано --listтолько это устройство, которое можно сузить до --id-only:

Команда:

xinput --list --id-only 'AlpsPS/2 ALPS DualPoint Stick'

вернет значение идентификатора указанного устройства:

11

Связанный контент