shell 如何使用find来匹配要连接的文件的子字符串?

zbsbpyhn  于 2023-03-24  发布在  Shell
关注(0)|答案(2)|浏览(129)

完全的初学者在这里,所以很抱歉,如果这是痛苦的明显.我试图写一个shell脚本ffmpeg concat协议一堆分裂的视频文件在一起,通过循环的文件和动态添加正确的部分被连接在一起.例如,把这个:
titlea-00001234-01.ts
titlea-00001234-02.ts
titlea-00001234-03.ts
titleb-00001234-01.ts
titleb-00004321-02.ts
titleb-00004321-03.ts
变成这样:
titlea-00001234.mp4
titleb-00004321.mp4
通过这样做

ffmpeg -i "concat:titlea-00001234-01.ts|titlea-00001234-02.ts|titlea-00001234-03.ts" -c copy titlea-00001234.mp4
ffmpeg -i "concat:titleb-00001234-01.ts|titleb-00001234-03.ts|titleb-00001234-03.ts" -c copy titleb-00001234.mp4

但是我遇到的麻烦是使用find在"concat:"之后添加正确的部分。
以下是我最好的尝试:

#!/bin/bash
for i in /path/to/files/*.ts
    do
        if [[ "$i" =~ (-01) ]]
        then
            j="${i##*/}"
            k="${j%-0*}"
            ffmpeg -i `concat:( find /path/to/files/ -type f -name "{$k}*" -exec printf "%s\0" {} + )` -c copy /path/to/output/"{$k%.ts}.mp4"
        else
            echo "no files to process"
            exit 0
        fi
    done

但这会导致“No such file or directory”的错误。

编辑此解决方案完美地满足了我的需求https://stackoverflow.com/a/75807616/21403800感谢@pjh和其他所有人花时间帮助

11dmarpk

11dmarpk1#

一种可能是

#!/bin/bash

for file in *-[0-9][0-9].ts; do
    prefix=${file%??????}
    tgtfile=$prefix.mp4
    [[ -e $tgtfile ]] && continue
    printf -v filelst '%s|' "$prefix"-[0-9][0-9].ts
    ffmpeg -i "concat:${filelst%?}" -c copy "$tgtfile"
done
smtd7mpg

smtd7mpg2#

试试这个Shellcheck-clean代码:

#! /bin/bash -p

shopt -s nullglob

cd path_to_files || exit 1

prev_base=
for tsfile in *-[[:digit:]][[:digit:]].ts ''; do
    base=${tsfile%-*}
    if [[ $base == "$prev_base" ]]; then
        iarg+="|$tsfile"
    else
        [[ -n $prev_base ]] && echo ffmpeg -i "$iarg" -c copy "${prev_base}.mp4"
        iarg="concat:$tsfile"
        prev_base=$base
    fi
done
  • shopt -s nullglob在没有匹配项时使glob扩展为nothing(否则它们扩展为glob模式本身,这在程序中几乎没有用)。
  • for tsfile in *-[[:digit:]][[:digit:]].ts ''; do中分号前的''是一个空字符串sentinel,用于使循环体中的代码处理*-[[:digit:]][[:digit:]].ts模式匹配的最后一批文件。
  • 有关${tsfile%-*}的解释,请参阅删除字符串的一部分(BashFAQ/100(如何在bash中进行字符串操作?))。
  • 代码当前仅打印要执行的ffmpeg命令。删除echo以使其实际运行ffmpeg命令。

相关问题