특정 파일 확장자를 포함하는 폴더에 루프하려면 어떻게 해야 합니까?

특정 파일 확장자를 포함하는 폴더에 루프하려면 어떻게 해야 합니까?

을(를) 사용하여 하위 폴더의 오디오 파일을 분할하고 싶습니다 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이와 같은 오류를 방지하려면 include 만 사용하도록 전환하고 싶습니다.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실행 find하고 실행합니다 . 스크립트 는 디렉토리의 대량 경로 이름으로 호출되지만 첫 번째 인수는 출력 디렉토리의 경로 이름이 됩니다. 이는 스크립트에서 수신 되며 매개변수는 위치 매개변수 목록 밖으로 이동되어 디렉토리 경로 이름 목록만 남습니다.findbashbashoutdirbash

그런 다음 인라인 스크립트는 이러한 디렉터리를 반복하고 *.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한 번도 사용해본 적이 없어서 아시죠?

관련 정보