我有一个cpp可执行文件(mycat),它可以从共享内存中连续读取一个循环的音频流,并将数据传输到stdOut,并将元数据信息传输到stdErr。mycat为音频流的每个条目排出12行,其中包含元数据信息,如下所示:
0x1 (TimeStamp) 12Bytes:2956 + 6793/(47999+1) (0.141521) delta= 0+ 1536/(47999+1) (0.032000) 2956.151418 -9.898ms 2016.04.04 16:06:37.700
0x4 (ReferenceTime) 12Bytes:2956 + 6156972/(26999999+1) (0.228036) delta= 0+ 1618519/(26999999+1) (0.059944) 2956.151426 76.610ms 2016.04.04 16:06:37.700
0x6 (ProcessDelay) 4Bytes: 64 (0x40)
0x7 (ClockAccuracy) 8Bytes: offset=0.000ppm (+-0.000ppm)
0xb (ClockId) 8Bytes: 01 00 00 00 42 22 01 00
0x20001 (SampleRate) 4Bytes: 48000 (0xbb80)
0x20002 (Channels) 4Bytes: 6 (0x6)
0x20003 (PcmLevel) 24Bytes: -21307 -20348 -31737 -42427 -28786 -26525
0x20004 (PcmPeak) 24Bytes: -14366 -13360 -25203 -39427 -19067 -21307
0x2000e (DolbyDpMetadata) 39352Bytes:
Linear Time: 2956 + 6793/(47999+1) (0.141521) delta= 0+ 1536/(47999+1) (0.032000)
2016.04.04 16:06:37.700 update: slot=0xe2840 validTo=0x3d1dd180 shmT=0x3d195200 (delta=294784) doffset=0xec2c0 msize=39552 dsize=18432 type=0x20001 (PCMS16) data bytes: df f4 f2 fc我想要的是一个bash脚本:
1)启动mycat eg../mycat shm_name > /dev/null。
2)将stdErr从mycat读取到第12行,无论从何处开始。
2.1)最终将12行存储到变量中(这是可选的)
3)在第12行之后立即杀死mycat,这样bash脚本就可以继续运行,而不会被输出的stdError所困扰。
4)读取行"Channels“的值(在本例中为6),并将其存储到一个名为"channels”的变量中。
5)读取行"SampleRate“的值(在本例中为48000),并将其存储为一个名为"rate”的变量。
有办法吗?
发布于 2016-04-06 08:50:46
我找到了一个优雅的解决方案:
while read -r line; # Read mycat line by line
do
if echo "$line" | grep -qi "SampleRate"; then # Search for line containing string 'SampleRate'
rate="${line#*:}"; # Remove all charachters till ':'
rate="${rate%(*}"; # Remove all charachters from '('
rate="$(echo -e "${rate}" | tr -d '[[:space:]]')" # Remove all tralling withespace
elif echo "$line" | grep -qi "Channels"; then
channels="${line#*:}";
channels="${channels%(*}";
channels="$(echo -e "${channels}" | tr -d '[[:space:]]')"
fi
if [ -n "$channels" ] && [ -n "$rate" ]; then # If both variables 'channels' and 'rate' are not empty kill the while loop
break;
fi
done < <(./mycat $shm_name 2>&1 > /dev/null) # Mycat is processed into a while loop, standard Error is redirected to standard Output ( 2>&1 )
echo "Found datarate: $rate"
echo "Found channels: $channels"发布于 2016-04-04 17:05:15
您可以使用mycat shm_name > /dev/null 2>/path/to/file重定向stderr。当时机成熟时,你可以用killall mycat杀死我的猫。对于存储变量,您需要export channels =,与速率相同的模式。你可以用grep找到那些。不过,我不知道怎么等十二行。
发布于 2016-04-04 17:34:16
首先,需要将STDERR重定向到STDOUT,并使STDOUT变为null。
mycat 2>&1 >/dev/null | parsing_script然后,您需要一个解析脚本来收集数据。
#!/bin/bash
declare -a data=()
count=1
while read line; do
data+=( "$line
")
((count++))
string=$(echo $line|sed 's/.*(\(.[A-Za-z]*\)).*/\1/')
case $string in
SampleRate) rate=$(echo $line|sed 's/.*: \(.[0-9]*\) .*/\1/')
;;
Channels) channels=$(echo $line|sed 's/.*: \(.[0-9]*\) .*/\1/')
;;
*) true;;
esac
if [[ $count -gt 12 ]]; then
break
fi
done <&0
echo $channels
echo $rate我回显了这些值,但是您可以将它们重定向到一个文件,格式化它们,等等。而且,${data@}包含您的元数据。因为你是管道,我正在读STDIN,但如果你想调整它,它可能会更健壮。
https://stackoverflow.com/questions/36408224
复制相似问题