2016-11-30 5 views
0

Обычно из терминала я использую команду:Как разобрать вывод списка pacmd и найти индексы и имена приемников с помощью QRegExp?

pacmd list-sinks|awk '/index:/ {print $0} /name:/ {print $0};' 

, который дает мне выход так:

index: 0 
    name: <alsa_output.pci-0000_01_00.1.hdmi-stereo> 
    index: 1 
    name: <alsa_output.pci-0000_00_1b.0.analog-stereo> 
    * index: 2 
    name: <alsa_output.usb-0d8c_C-Media_USB_Audio_Device-00-Device.iec958-stereo> 

, но, по-видимому из Qt, когда командует с помощью QProcess, разбора с помощью awk не работает , он просто не выполняет никакого анализа и производит весь вывод, который вы ожидаете от команды pacmd list-sinks. Весь вывод следующий:

Welcome to PulseAudio! Use "help" for usage information. 
>>> 3 sink(s) available. 
    index: 0 
    name: <alsa_output.pci-0000_01_00.1.hdmi-stereo> 
    driver: <module-alsa-card.c> 
    flags: HARDWARE DECIBEL_VOLUME LATENCY DYNAMIC_LATENCY 
    state: SUSPENDED 
    suspend cause: IDLE 
    priority: 9050 
    volume: 0: 45% 1: 45% 
      0: -20,78 dB 1: -20,78 dB 
      balance 0,00 
    base volume: 100% 
       0,00 dB 
    volume steps: 65537 
    muted: no 
    current latency: 0,00 ms 
    max request: 0 KiB 
    max rewind: 0 KiB 
    monitor source: 0 
    sample spec: s16le 2ch 44100Hz 
    channel map: front-left,front-right 
       Stereo 
    used by: 0 
    linked by: 0 
    configured latency: 0,00 ms; range is 0,50 .. 371,52 ms 
    card: 0 <alsa_card.pci-0000_01_00.1> 
    module: 5 
    properties: 
     alsa.resolution_bits = "16" 
     device.api = "alsa" 
     device.class = "sound" 
     alsa.class = "generic" 
     alsa.subclass = "generic-mix" 
     alsa.name = "HDMI 0" 
     alsa.id = "HDMI 0" 
     alsa.subdevice = "0" 
     alsa.subdevice_name = "subdevice #0" 
     alsa.device = "3" 
     alsa.card = "1" 
     alsa.card_name = "HDA NVidia" 
     alsa.long_card_name = "HDA NVidia at 0xf7080000 irq 17" 
     alsa.driver_name = "snd_hda_intel" 
     device.bus_path = "pci-0000:01:00.1" 
     sysfs.path = "/devices/pci0000:00/0000:00:01.0/0000:01:00.1/sound/card1" 
     device.bus = "pci" 
     device.vendor.id = "10de" 
     device.vendor.name = "NVIDIA Corporation" 
     device.product.id = "0e1b" 
     device.product.name = "GK107 HDMI Audio Controller" 
     device.string = "hdmi:1" 
     device.buffering.buffer_size = "65536" 
     device.buffering.fragment_size = "32768" 
     device.access_mode = "mmap+timer" 
     device.profile.name = "hdmi-stereo" 
     device.profile.description = "Digital Stereo (HDMI)" 
     device.description = "GK107 HDMI Audio Controller Digital Stereo (HDMI)" 
     alsa.mixer_name = "Nvidia GPU 42 HDMI/DP" 
     alsa.components = "HDA:10de0042,104383f3,00100100" 
     module-udev-detect.discovered = "1" 
     device.icon_name = "audio-card-pci" 
    ports: 
     hdmi-output-0: HDMI/DisplayPort (priority 5900, latency offset 0 usec, available: no) 
      properties: 
       device.icon_name = "video-display" 
    active port: <hdmi-output-0> 
    index: 1 
    name: <alsa_output.pci-0000_00_1b.0.analog-stereo> 
    driver: <module-alsa-card.c> 
    flags: HARDWARE HW_MUTE_CTRL HW_VOLUME_CTRL DECIBEL_VOLUME LATENCY DYNAMIC_LATENCY 
    state: SUSPENDED 
    suspend cause: IDLE 
    priority: 9959 
    volume: 0: 27% 1: 27% 
      0: -34,20 dB 1: -34,20 dB 
      balance 0,00 
    base volume: 100% 
       0,00 dB 
    volume steps: 65537 
    muted: no 
    current latency: 0,00 ms 
    max request: 0 KiB 
    max rewind: 0 KiB 
    monitor source: 1 
    sample spec: s16le 2ch 48000Hz 
    channel map: front-left,front-right 
       Stereo 
    used by: 0 
    linked by: 0 
    configured latency: 0,00 ms; range is 0,50 .. 341,33 ms 
    card: 1 <alsa_card.pci-0000_00_1b.0> 
    module: 6 
    properties: 
     alsa.resolution_bits = "16" 
     device.api = "alsa" 
     device.class = "sound" 
     alsa.class = "generic" 
     alsa.subclass = "generic-mix" 
     alsa.name = "ALC269VB Analog" 
     alsa.id = "ALC269VB Analog" 
     alsa.subdevice = "0" 
     alsa.subdevice_name = "subdevice #0" 
     alsa.device = "0" 
     alsa.card = "0" 
     alsa.card_name = "HDA Intel PCH" 
     alsa.long_card_name = "HDA Intel PCH at 0xf7330000 irq 38" 
     alsa.driver_name = "snd_hda_intel" 
     device.bus_path = "pci-0000:00:1b.0" 
     sysfs.path = "/devices/pci0000:00/0000:00:1b.0/sound/card0" 
     device.bus = "pci" 
     device.vendor.id = "8086" 
     device.vendor.name = "Intel Corporation" 
     device.product.id = "1e20" 
     device.product.name = "7 Series/C210 Series Chipset Family High Definition Audio Controller" 
     device.form_factor = "internal" 
     device.string = "front:0" 
     device.buffering.buffer_size = "65536" 
     device.buffering.fragment_size = "32768" 
     device.access_mode = "mmap+timer" 
     device.profile.name = "analog-stereo" 
     device.profile.description = "Analog Stereo" 
     device.description = "Built-in Audio Analog Stereo" 
     alsa.mixer_name = "Realtek ALC269VB" 
     alsa.components = "HDA:10ec0269,1028052c,00100100" 
     module-udev-detect.discovered = "1" 
     device.icon_name = "audio-card-pci" 
    ports: 
     analog-output: Analog Output (priority 9900, latency offset 0 usec, available: unknown) 
      properties: 

     analog-output-speaker: Speakers (priority 10000, latency offset 0 usec, available: no) 
      properties: 
       device.icon_name = "audio-speakers" 
     analog-output-headphones: Headphones (priority 9000, latency offset 0 usec, available: yes) 
      properties: 
       device.icon_name = "audio-headphones" 
    active port: <analog-output-headphones> 
    * index: 2 
    name: <alsa_output.usb-0d8c_C-Media_USB_Audio_Device-00-Device.iec958-stereo> 
    driver: <module-alsa-card.c> 
    flags: HARDWARE DECIBEL_VOLUME LATENCY DYNAMIC_LATENCY 
    state: RUNNING 
    suspend cause: 
    priority: 9048 
    volume: 0: 45% 1: 45% 
      0: -20,78 dB 1: -20,78 dB 
      balance 0,00 
    base volume: 100% 
       0,00 dB 
    volume steps: 65537 
    muted: no 
    current latency: 31,29 ms 
    max request: 4 KiB 
    max rewind: 344 KiB 
    monitor source: 4 
    sample spec: s16le 2ch 48000Hz 
    channel map: front-left,front-right 
       Stereo 
    used by: 1 
    linked by: 1 
    configured latency: 26,00 ms; range is 26,00 .. 1837,50 ms 
    card: 3 <alsa_card.usb-0d8c_C-Media_USB_Audio_Device-00-Device> 
    module: 22 
    properties: 
     alsa.resolution_bits = "16" 
     device.api = "alsa" 
     device.class = "sound" 
     alsa.class = "generic" 
     alsa.subclass = "generic-mix" 
     alsa.name = "USB Audio" 
     alsa.id = "USB Audio" 
     alsa.subdevice = "0" 
     alsa.subdevice_name = "subdevice #0" 
     alsa.device = "0" 
     alsa.card = "2" 
     alsa.card_name = "C-Media USB Audio Device" 
     alsa.long_card_name = "C-Media USB Audio Device at usb-0000:00:14.0-1, full speed" 
     alsa.driver_name = "snd_usb_audio" 
     device.bus_path = "pci-0000:00:14.0-usb-0:1:1.0" 
     sysfs.path = "/devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1:1.0/sound/card2" 
     udev.id = "usb-0d8c_C-Media_USB_Audio_Device-00-Device" 
     device.bus = "usb" 
     device.vendor.id = "0d8c" 
     device.vendor.name = "C-Media Electronics, Inc." 
     device.product.id = "000c" 
     device.product.name = "Audio Adapter" 
     device.serial = "0d8c_C-Media_USB_Audio_Device" 
     device.string = "iec958:2" 
     device.buffering.buffer_size = "352800" 
     device.buffering.fragment_size = "176400" 
     device.access_mode = "mmap+timer" 
     device.profile.name = "iec958-stereo" 
     device.profile.description = "Digital Stereo (IEC958)" 
     device.description = "Audio Adapter Digital Stereo (IEC958)" 
     alsa.mixer_name = "USB Mixer" 
     alsa.components = "USB0d8c:000c" 
     module-udev-detect.discovered = "1" 
     device.icon_name = "audio-card-usb" 
    ports: 
     iec958-stereo-output: Digital Output (S/PDIF) (priority 0, latency offset 0 usec, available: unknown) 
      properties: 

    active port: <iec958-stereo-output> 
>>> 

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

QString prog = "pacmd"; 
QStringList arguments; 
QProcess p; 
arguments << "list-sinks"<<"|awk '/index:/ {print $0} /name:/ {print $0};'"; 
QString reply; 
p.start(prog, arguments); 
if (p.waitForStarted()) 
{ 
    p.waitForFinished(); 
    reply = p.readAllStandardOutput(); 
    qDebug()<<reply<<endl; 
} 
else 
{ 
    qDebug()<< "Error using pacmd for getting list of sinks"; 
} 

Итак, теперь, я пытаюсь разобрать индексы и имена без использования awk. Я могу найти индексы, но не имена. Код выглядит следующим образом:

QString prog = "pacmd"; 
QStringList arguments; 
QProcess p; 
arguments << "list-sinks"; 
QString reply; 
p.start(prog, arguments); 
if (p.waitForStarted()) 
{ 
    p.waitForFinished(); 
    reply = p.readAllStandardOutput(); 
    QRegExp rx("index: \\d+|'", Qt::CaseInsensitive); 
    QStringList indexList; 
    int pos = 0; 
    while ((pos = rx.indexIn(reply, pos)) != -1) { 
     indexList << rx.capturedTexts(); 
     pos += rx.matchedLength(); 
    } 
    foreach (QString index, indexList) { 
     qDebug()<<index; 
    } 

    QRegExp rx1("name: \\s*|'", Qt::CaseInsensitive); 
    QStringList nameList; 
    pos = 0; 
    while ((pos = rx1.indexIn(reply, pos)) != -1) { 
     nameList << rx1.capturedTexts(); 
     pos += rx1.matchedLength(); 
    } 
    foreach (QString index, nameList) { 
     qDebug()<<index; 
    } 
} 
else 
{ 
    qDebug()<< "Error using pacmd for getting list of sinks"; 
} 

выходной я получаю от кода следующее:

"index: 0" 
"index: 1" 
"index: 2" 
"name: " 
"name: " 
"name: " 

Как я могу получить имена, а как следующую строку?

name: <alsa_output.pci-0000_01_00.1.hdmi-stereo> 

ли "name: \\s*|'" не правильный шаблон для регулярного выражения для захвата имя, а?

Спасибо.

+1

Думаю, вам понадобятся два экземпляра 'QProcess' - один для' pacmd', а другой для 'awk'. Затем подключите вывод одного к другому с помощью ['QProcess :: setStandardOutputProcess'] (http://doc.qt.io/qt-5/qprocess.html#setStandardOutputProcess). –

+0

Ваше предложение приведет меня к этому ответу :) http: // stackoverflow.ком/вопросы/20901884/трубопроводы или-командной цепочки-с-QProcess –

ответ

2

Во-первых причина, почему ваш первый попробовать запустить AWK не работает:

Труба «|» является особенностью оболочки (например, bash). Когда вы запускаете исполняемый файл с QProcess, это не запускает исполняемый файл в оболочке, он запускает исполняемый файл напрямую. В вашем коде исполняемый файл pacmd запускается с аргументами командной строки list-sinks и |awk '/index:/ {print $0} /name:/ {print $0};'.

Чтобы сделать его работу вам необходимо либо первый запуск list-sinks, получить свою продукцию, а затем запустить awk и передать его это как вход, или, если вы хорошо с в зависимости от конкретной оболочки, вы также можете запустить оболочку и передайте ему свою командную строку (в случае с bash вы должны передать -c и pacmd list-sinks|awk '/index:/ {print $0} /name:/ {print $0};' в качестве аргументов /bin/bash).

Что касается синтаксического анализа для name: something с регулярными выражениями, выражение \s ссылок пробельные. Так что просто измените name: \\s* на name: \\S* (с верхним регистром S) для получения символов без пробелов.