处理 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()
调用两次一次,以替换前导空格和其他以删除数字后面的 %
符号。
我写的这个脚本可能就是你想要的。它让我可以使用 pacmd
和 pactl
命令轻松调节音量。当我使用 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
寻找从
中提取音量的方法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()
调用两次一次,以替换前导空格和其他以删除数字后面的 %
符号。
我写的这个脚本可能就是你想要的。它让我可以使用 pacmd
和 pactl
命令轻松调节音量。当我使用 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