处理 bash 中的文本 - 从 pactl sink-inputs 输出中提取程序量

Processing text in bash - extracting the volume of a program from pactl sink-inputs output

寻找从

中提取音量的方法
pactl list sink-inputs

输出示例:

Sink Input #67
        Driver: protocol-native.c
        Owner Module: 12
        Client: 32
        Sink: 0
        Sample Specification: s16le 2ch 44100Hz
        Channel Map: front-left,front-right
        Format: pcm, format.sample_format = "\"s16le\""  format.channels = "2"  format.rate = "44100"  format.channel_map = "\"front-left,front-right\""
        Corked: no
        Mute: no
        Volume: front-left: 19661 /  30% / -31.37 dB,   front-right: 19661 /  30% / -31.37 dB
                balance 0.00
        Buffer Latency: 100544 usec
        Sink Latency: 58938 usec
        Resample method: n/a
        Properties:
                media.name = "'Alerion' by 'Asking Alexandria'"
                application.name = "Clementine"
                native-protocol.peer = "UNIX socket client"
                native-protocol.version = "32"
                media.role = "music"
                application.process.id = "16924"
                application.process.user = "gray"
                application.process.host = "gray-kubuntu"
                application.process.binary = "clementine"
                application.language = "en_US.UTF-8"
                window.x11.display = ":0"
                application.process.machine_id = "54f542f950a5492c9c335804e1418e5c"
                application.process.session_id = "3"
                application.icon_name = "clementine"
                module-stream-restore.id = "sink-input-by-media-role:music"
                media.title = "Alerion"
                media.artist = "Asking Alexandria"                           

我要提取

30

来自行

 Volume: front-left: 19661 /  30% / -31.37 dB,   front-right: 19661 /  30% / -31.37 dB

注意:可能有多个sink input,我只需要从Sink Input #67提取音量

谢谢

P.S。需要这个用于我的脚本,它应该增加或减少我的音乐播放器的音量。我对 linux 和 bash 都是全新的,所以我想不出解决问题的方法。

编辑: 我的 awk 版本

gray@gray-kubuntu:~$ awk -W version
mawk 1.3.3 Nov 1996, Copyright (C) Michael D. Brennan

compiled limits:
max NF             32767
sprintf buffer      2040

由于您对使用标准的文本处理工具还很陌生,我将提供一个带有详细解释的答案。以后随意使用。

我使用我安装的 GNU Awk 来回答这个问题,它应该也适用于您系统中安装的 mawk

pactl list sink-inputs | \
    mawk '/Sink Input #67/{f=1; next} f && /Volume:/{ n=split([=10=],matchGroup,"/"); val=matchGroup[2]; gsub(/^[[:space:]]+/,"",val); gsub(/%/,"",val); print val; f=0}'

Awk 基于 /pattern/{action1; action2} 语法一次处理一行。但是在我们的例子中,我们匹配行 /Sink Input #67/ 并启用一个标志(f)来标记下面行中下一次出现的 Volume: 字符串。如果没有设置标志,它可以匹配其他接收器输入的实例。

因此,一旦我们匹配了该行,我们就使用分隔符 / 拆分该行,并获得存储在数组中的第二个匹配元素 (matchGroup)。然后我们使用 gsub() 调用两次一次,以替换前导空格和其他以删除数字后面的 % 符号。

我写的这个脚本可能就是你想要的。它让我可以使用 pacmdpactl 命令轻松调节音量。当我使用 GNOME 桌面(Wayland 或 Xorg)时似乎运行良好,目前它在 RHEL/Fedora 和 Ubuntu 上运行。我还没有尝试将它与其他 desktops/distros 或环绕声系统等一起使用

将它放在您的路径中,然后 运行 它没有任何值以查看当前音量。或者通过传递一个百分比来设置音量。单个值设置两个扬声器,两个值将分别设置左和右。从理论上讲,您不应使用 0%-200% 之外的值,但脚本不会对此进行检查(PulseAudio 显然也不会),所以要小心,因为高于 200% 的音量可能会损坏您的扬声器。

[~]# volume
L    R   
20%  20% 
[~]# volume 100% 50%
[~]# volume
L    R   
100% 50% 
[~]# volume 80%
[~]# volume
L    R   
80%  80% 
#!/bin/bash

[ ! -z "" ] && [ $# -eq 1 ] && export LVOL="" && export RVOL=""
[ ! -z "" ] && [ ! -z "" ] && [ $# -eq 2 ]  && export LVOL="" && export RVOL=""

SINK=$(pacmd list-sinks | grep -e '* index:' | grep -Eo "[0-9]*$")

if [ -z "$LVOL" ] || [ -z "$RVOL" ]; then
  # pacmd list-sinks | grep -e '* index:' -A 20 | grep -e 'name:' -e '^\s*volume:.*\n' -e 'balance' --color=none
  printf "%-5s%-4s\n%-5s%-4s\n" "L" "R" $(pacmd list-sinks | grep -e '* index:' -A 20 | grep -e '^\s*volume:.*\n' --color=none | grep -Eo "[0-9]*%" | tr  "\n" " " | sed "s/ $/\n/g")
  exit 0
elif [[ ! "$LVOL" =~ ^[0-9]*%$ ]] || [[ ! "$RVOL" =~ ^[0-9]*%$ ]]; then
  printf "The volume should specified as a percentage, from 0%% to 200%%.\n"
  exit 1
elif [ "$SINK" == "" ]; then
  printf "Unable to find the default sound output.\n"
  exit 1
fi

pactl -- set-sink-volume $SINK $LVOL $RVOL