从文本中提取 2 行不同且不连续的行而不创建临时文本文件

问题描述 投票:0回答:4

本人是音乐人,兼职会编程,能力有限,请见谅

有时我需要多个音频文件的 LUFS 级别,而最快的方法(对我来说......)是使用 ffmpeg 来计算它,因为它会在几秒钟内离线处理一个文件,而不必全部播放在 DAW 中进行读数的方式。

这是我想出的剧本:

#!/bin/zsh

TempDirectory="~/Desktop/TEMP"

TempRAW="$TempDirectory/ffmpeg_LUFS_output_RAW.txt"
OutputCSV="$TempDirectory/ffmpeg_LUFS_output.csv"

for CurrentFile in "$@" 
do

    echo "File: "$(/usr/bin/basename "$CurrentFile") >>"$TempRAW"

    /opt/homebrew/bin/ffmpeg -i "$CurrentFile" -hide_banner -af ebur128=framelog=verbose -f null - 2>>"$TempRAW"

done

# The next part extracts the info from the raw ffmpeg output file 
# The output from ffmpeg is 55 lines
# Line 1:  File: LSK Adore v18 [Dreamy] MIX ALL Stereo.wav
# ... snip ...
# Line 47: Integrated loudness:
# Line 48:   I:         -32.2 LUFS
# Line 49:   Threshold: -42.6 LUFS
#
# The lines that interest me are Line 1 + 48:


while IFS= read -r line
do

    if [[ "$line" =~ ^"File: " ]]; then
    printf "$line," | sed 's/File: //' >>"$OutputCSV"
    fi

    if [[ "$line" =~ ^"    I:" ]]; then
    echo "$line" | sed 's/    I:         //'>>"$OutputCSV"
    fi

done < "$TempRAW"


有效,我的问题解决了,我的能力如何让我解决了它。

但我宁愿不必写临时文件。

写这篇文章时,我至少搜索了 4 个小时来寻找解决方案。他们中的大多数人解释说要使用 awk 处理存储在变量中的 ffmpeg 输出。但是 awk 总是会为第一个条目创建双倍的结果(我可能做错了什么......)。

没有临时文件我怎么写这个?

这里是输出的更多示例行:

File: LSK Adore v18 [Dreamy] MIX ALL Stereo.wav
Guessed Channel Layout for Input Stream #0.0 : stereo
Input #0, wav, from '/Volumes/Project HDD/Leopard Skin/Themes/Bounces/LSK Adore v18 STEMS 78bpm/LSK Adore v18 [Dreamy] MIX ALL Stereo.wav':
  Metadata:
    encoded_by      : Logic Pro X
    originator_reference: aaO3N!Fzk7Rk
    date            : 2021-05-24
    creation_time   : 18:48:28
    time_reference  : 276258449
...
SNIP
...
size=       0kB time=00:00:00.00 bitrate=N/A speed=N/A    
size=N/A time=00:01:49.21 bitrate=N/A speed= 766x    
video:0kB audio:20481kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown
[Parsed_ebur128_0 @ 0x153f0af90] Summary:

  Integrated loudness:
    I:         -32.2 LUFS
    Threshold: -42.6 LUFS

  Loudness range:
    LRA:         4.9 LU
    Threshold: -52.7 LUFS
    LRA low:   -34.5 LUFS
    LRA high:  -29.6 LUFS
bash awk
4个回答
0
投票

您可以将输出通过管道传输到

sed
,并让它过滤第一行(
1p
),以及包含“综合响度”(
/Integrated loudness/{n;p}
)的行下面的行:

ffmpeg -i "$CurrentFile" … 2>&1 | sed -n '1p;/Integrated loudness/{n;p}'
File: LSK Adore v18 [Dreamy] MIX ALL Stereo.wav
    I:         -32.2 LUFS

0
投票

你真正需要的概念只是 unix 管道 (

|
):

    for CurrentFile in "$@" 
    do
    
        echo $(/usr/bin/basename "$CurrentFile") >>"$OutputCSV"
    
        /opt/homebrew/bin/ffmpeg -i "$CurrentFile" -hide_banner -af ebur128=framelog=verbose -f null - |&

while IFS= read -r line
do

    if [[ "$line" =~ ^"    I:" ]]; then
    echo "$line" | sed 's/    I:         //'>>"$OutputCSV"
    fi

done 
    
    done

0
投票

这可以用一个循环来完成。一种方法是:

for CurrentFile in "$@"; do
    printf '%s,' "${CurrentFile##*/}"
    ffmpeg -i "$CurrentFile" -hide_banner -af ebur128=framelog=verbose -f null - 2> >(sed -n 's/^[[:blank:]]*I:[[:blank:]]*//p')
done > "$OutputCSV"

0
投票

假设:

  • 我们只想要字符串
    ^File:<white space>
    <white_space>I:<white_space>
  • 之后的数据

一个

awk
想法:

awk '{ if (match($0,/^File:[[:space:]]*|^.[[:space:]]*I:[[:space:]]*/)) print substr($0,RSTART+RLENGTH) }'

地点:

  • 我们寻找两种模式之一的匹配:
  • ^File:[[:space:]]*
  • ^.[[:space:]]*I:[[:space:]]*
  • if
    match(...)
    返回一个非零值然后...
  • substr($0,RSTART+RLENGTH)
    提取匹配后出现的那部分行(
    RSTART
    RLENGTH
    由成功的
    match(...)
    设置)

OP 然后可以通过以下两种方法之一将

ffmpeg
输出提供给此命令:

ffmpeg ... | awk '{ .... }'

# or

awk '{ .... }' < <(ffmpeg ...)

使用本地文件模拟OP的

ffmpeg
输出:

$ cat ffmpeg.out
File: LSK Adore v18 [Dreamy] MIX ALL Stereo.wav
Guessed Channel Layout for Input Stream #0.0 : stereo
Input #0, wav, from '/Volumes/Project HDD/Leopard Skin/Themes/Bounces/LSK Adore v18 STEMS 78bpm/LSK Adore v18 [Dreamy] MIX ALL Stereo.wav':
  Metadata:
    encoded_by      : Logic Pro X
    originator_reference: aaO3N!Fzk7Rk
    date            : 2021-05-24
    creation_time   : 18:48:28
    time_reference  : 276258449
...
SNIP
...
size=       0kB time=00:00:00.00 bitrate=N/A speed=N/A
size=N/A time=00:01:49.21 bitrate=N/A speed= 766x
video:0kB audio:20481kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown
[Parsed_ebur128_0 @ 0x153f0af90] Summary:

  Integrated loudness:
    I:         -32.2 LUFS
    Threshold: -42.6 LUFS

  Loudness range:
    LRA:         4.9 LU
    Threshold: -52.7 LUFS
    LRA low:   -34.5 LUFS
    LRA high:  -29.6 LUFS

通过

awk
代码运行:

$ cat ffmpeg.out | awk '{ if (match($0,/^File:[[:space:]]*|^.[[:space:]]*I:[[:space:]]*/)) print substr($0,RSTART+RLENGTH) }'
LSK Adore v18 [Dreamy] MIX ALL Stereo.wav
-32.2 LUFS

或者我们可以将

awk
脚本放在一个文件中:

$ cat ffmpeg.awk
{ if (match($0,/^File:[[:space:]]*|^.[[:space:]]*I:[[:space:]]*/)) print substr($0,RSTART+RLENGTH) }

调用变成:

$ cat ffmpeg.out | awk -f ffmpeg.awk
LSK Adore v18 [Dreamy] MIX ALL Stereo.wav
-32.2 LUFS
© www.soinside.com 2019 - 2024. All rights reserved.