如何循环进入包含特定文件扩展名的文件夹?

如何循环进入包含特定文件扩展名的文件夹?

我想将子文件夹中的分割音频文件与Sox.我有这个基本脚本

#!/bin/bash

# Example: sox_merge_subfolder.sh input_dir/ output_dir/

# Soure directory with subfolder that contains splitted mp3
input_dir=$1

# Set the directory you want for the merged mp3s
output_dir=$2

# make sure the output directory exists (create it if not)
mkdir -p "$output_dir"

find "$input_dir" -type d -print0 | while read -d $'\0' file
do
  echo "Processing..."
  cd "$file"
  output_file="$output_dir/${PWD##*/} - Track only.mp3"
  echo "  Output: $output_file"
  sox --show-progress *.mp3 "$output_file"
done

它正在工作,但我想切换到仅使用包含mp3.为了避免像这样的错误sox FAIL formats: can't open input file '*.mp3': No such file or directory

我有这个有效的命令find . -maxdepth 2 -name "*.mp3" -exec dirname {} \; | uniq。但路径是相对的,我无法将其包含到现有的脚本中。

答案1

我们仍然可以用来find查找所有目录,但是获取这些目录的循环必须测试 MP3 文件:

#!/bin/sh

indir=$1
outdir=$2

mkdir -p "$outdir" || exit 1

find "$indir" -type d -exec bash -O nullglob -c '
    outdir=$1; shift

    for dirpath do
        mp3files=( "$dirpath"/*.mp3 )
        [[ ${#mp3files[@]} -eq 0 ]] && continue

        printf -v outfile "%s - Track only.mp3" "${dirpath##*/}"

        sox --show-progress "${mp3files[@]}" "$outdir/$outfile"
    done' bash "$outdir" {} +

/bin/sh脚本运行findfind运行一个简短的内联bash脚本。该bash脚本将使用目录的批量路径名来调用,但第一个参数将是输出目录的路径名。这是在outdir脚本中接收的bash,并且该参数从位置参数列表中移出,只留下目录路径名列表。

然后,内联脚本迭代这些目录,并扩展*.mp3每个目录中的 glob,生成我们存储在数组中的 MP3 文件的路径名列表mp3files

由于我们使用-O nullglob此脚本,如果没有匹配的文件名,则数组将为空,因此-eq 0如果是这种情况,则使用测试跳到下一次迭代。

然后,我们从当前目录路径名构造输出文件名,并对sox收集的 MP3 文件名运行命令。

也可以看看:

答案2

cd在子外壳中执行

#!/usr/bin/env bash

shopt -s nullglob

input_dir=$1
output_dir=$2

mkdir -p "$output_dir"

while IFS= read -rd '' dir; do
  files=("$dir"/*.mp3)
  if (( ${#files[*]} )); then
    ( 
     cd "$dir" || exit
     output_file=$output_dir/${PWD##*/}
     echo " Output: $output_file"
     echo sox --show-progress "${files[@]##*/} "$output_file"
    )
  fi 
done < <(find "$input_dir" -type d -print0)
  • 如果您认为输出正确,请删除echo前面的。sox
  • sox以前从未使用过,所以你知道。

相关内容