Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Bash 从数组中排序字符串需要很长时间_Bash_Sorting - Fatal编程技术网

Bash 从数组中排序字符串需要很长时间

Bash 从数组中排序字符串需要很长时间,bash,sorting,Bash,Sorting,将文本文件读入数组、提取元素并对其排序需要很长时间 文本文件是用于R128音频分析的ffmpeg控制台输出。我需要得到最高的M和S值。例如: [Parsed_ebur128_0 @ 0x7fd32a60caa0] t: 4.49998 M: -22.2 S: -29.9 I: -27.0 LUFS LRA: 9.8 LU FTPK: -12.4 dBFS TPK: -9.7 dBFS [Parsed_ebur128_0 @ 0x7fd32a60caa0] t:

将文本文件读入数组、提取元素并对其排序需要很长时间

文本文件是用于R128音频分析的ffmpeg控制台输出。我需要得到最高的M和S值。例如:

[Parsed_ebur128_0 @ 0x7fd32a60caa0] t: 4.49998    M: -22.2 S: -29.9     I: -27.0 LUFS     LRA:   9.8 LU  FTPK: -12.4 dBFS  TPK:  -9.7 dBFS  
[Parsed_ebur128_0 @ 0x7fd32a60caa0] t: 4.69998    M: -22.5 S: -28.6     I: -25.9 LUFS     LRA:  11.3 LU  FTPK: -12.7 dBFS  TPK:  -9.7 dBFS
根据所分析音频文件的持续时间,文本文件的长度可以是数百行或数千行
我想找到最高的M(-22.2)和S值(-28.6),并将它们赋给变量M和S

这是我目前正在使用的:

ARRAY=()
while read LINE
do
ARRAY+=("$LINE")
done < $tempDir/text.txt

for LINE in "${ARRAY[@]}"
do
echo "$LINE" | sed -n ‘/B:/p' | sed 's/S:.*//' | sed -n -e 's/^.*M://p' | sed -n -e 's/-//p' >>/$tempDir/R128M.txt
done
for LINE in "${ARRAY[@]}"
do
echo "$LINE" | sed -n '/M:/p' | sed 's/I:.*//' | sed -n -e 's/^.*S://p' | sed -n -e 's/-//p' >>$tempDir/R128S.txt
done

cat $tempDir/R128M.txt
M=( $(sort $tempDir/R128M.txt) )

cat $tempDir/R128S.txt
S=( $(sort $tempDir/R128S.txt) )  
ARRAY=()
读行时
做
数组+=(“$LINE”)
完成<$tempDir/text.txt
对于“${ARRAY[@]}”中的行
做
echo“$LINE”| sed-n'/B:/p'| sed's/s:.*/'| sed-n-e's/^.*M://p'| sed-n-e's/-//p'>>/$tempDir/R128M.txt
完成
对于“${ARRAY[@]}”中的行
做
echo“$LINE”| sed-n'/M:/p'| sed's/I:.*/'| sed-n-e's/^.*s://p'| sed-n-e's/-///p'>>$tempDir/R128S.txt
完成
cat$tempDir/R128M.txt
M=($(排序$tempDir/R128M.txt))
目录$tempDir/R128S.txt
S=($(排序$tempDir/R128S.txt))

有没有更快的方法

与其读取内存中的整个文件,将其中的位写入单独的文件,然后再次读取,不如解析它并选择最大值:

$ awk '$7 > m || m == "" { m = $7 } $9 > s || s == "" { s = $9 } END { print m, s }' data
-22.2 -28.6
在您的数据中,字段7和9包含M和S的值。
awk
脚本将更新其
M
S
变量,如果它在这些字段中找到较大的值,然后打印最后找到的最大值。如果尚未读取任何值,则需要使用
m==“”
s==“”
来触发值的初始化

使用awk的另一种方式,可能看起来更干净:

$ awk 'FNR == 1 { m = $7; s = $9; next } $7 > m { m = $7 } $9 > s { s = $9 } END { print m, s }' data
要将它们分配给shell中的
M
S
,请执行以下操作:

$ declare $( awk 'FNR == 1 { m = $7; s = $9; next } $7 > m { m = $7 } $9 > s { s = $9 } END { printf("M=%f S=%f\n", m, s) }' data )

$ echo $M $S
-22.200000 -28.600000

调整
printf()
格式以使用
%s
而不是
%f
,如果您想要原始字符串而不是浮点值,或者设置您可能需要的小数位数,例如,
%.2f
代替
%f

首先,三个流程管道对于单个值提取来说有点多余,特别是考虑到你对每一行重新测试


接下来,将所有值保存到一个文件中,然后对该文件进行排序,而所需的只是最大值。您可以在第一个(值提取)循环中轻松找到它,以获得额外的
O(N)
运行时间,而不是所有I/O开销和
O(NlogN)
排序费用的I/O和排序。请参阅bash手册中的算术展开和条件表达式。

Yes。由于速度快,人们通常不会选择用bash脚本编写。即使是一个合适的perl脚本在这里也可能给您带来一个数量级的速度提升,特别是考虑到它主要是正则表达式处理。感谢您在脚本中添加要分配的其他信息。