0

我搜索了许多论坛和网站,以从我的 FLAC 集合中创建一个具有相同目录结构的 ALAC 集合,但没有成功。因此,我编写了自己的 shell 脚本并决定在这里分享,以便其他人可以使用或改进它。

我想解决的问题:

  1. 完全自动化的转换。我不想在每个目录中运行脚本。
  2. 递归文件搜索
  3. 通过将 flac 转换为 alac 并复制艺术品,将所有结构从一个位置移动到另一个位置。没有其他的。
  4. 我不希望 flac 和 alac 文件在同一个目录中。(我相信下面的脚本可以做到这一点)

这是脚本的结果。它对我有用,我希望它也对你有用。我正在使用 Linux Mint 和 bash shell。

2014-12-08 - 进行了一些更改,现在它工作正常。在它创建多个副本之前。

Usage is: ./FLACtoALAC.sh /sourcedirectory /targetdirectory

Here are some explanations:

Source: /a/b/c/d/e/   <- e has flac
              /g/f/k  <- k has artwork
                  /l  <- l has mp3

Target: /z/u/v/g/f

when the command is run : ./FLACtoALAC.sh /a/b/ /z/u/

I want the structure look like:
/z/u/v/g/f     <- f was already there
    /c/d/e/    <- e had flac, so created with the tree following source (/a/b) 
    /c/g/f/k   <- k had artwork, so created with the tree following source (/a/b) 

not created l  <- l did not have any of the png,jpg or flac files.

I do not want to create any directory that does not contain png, jpg or flac,
unless it is a parent to one of such those directories.    

现在更新的代码:

#!/bin/bash
if [[ $1 ]]
                then
                if [[ ${1:0:1} = / || ${1:0:1} = ~ ]]
                                then Source_Dir=$1
                elif [[ ${1:0:1} = . ]]          
                                then Source_Dir=`pwd`
                else Source_Dir=`pwd`'/'$1
                fi
else Source_Dir=`pwd`'/'
fi
if [[ $2 ]]
                then
                if [[ ${2:0:1} = / || ${2:0:1} = ~ ]]
                                then Target_Dir=$2
                elif [[ ${2:0:1} = . ]]          
                                then Target_Dir=`pwd`
                else Target_Dir=`pwd`'/'$2
                fi
else Target_Dir=`pwd`'/'
fi
echo "Source Directory : "$Source_Dir
echo "Target Directory : "$Target_Dir
typeset -i Source_Dir_Depth
Source_Dir_Depth=`echo $Source_Dir | grep -oi "\/" | wc -l`
typeset -i Target_Dir_Depth
Target_Dir_Depth=`echo $Target_Dir | grep -oi "\/" | wc -l`
echo "Depth of the Source Directory: "$Source_Dir_Depth
echo "Depth of the Target Directory: "$Target_Dir_Depth

echo "Let's check if the Target Directory exists, if not we will create"
typeset -i Number_of_depth_checks
Number_of_depth_checks=$Target_Dir_Depth+1
for depth in `seq 2 $Number_of_depth_checks`
    do
    Target_Directory_Tree=`echo ${Target_Dir} | cut -d'/' -f-${depth}`
    if [[ -d "$Target_Directory_Tree" ]]
    then
        echo "This directory exists ("$Target_Directory_Tree"), moving on"
    else 
        Create_Directory=`echo ${Target_Dir} | cut -d'/' -f-${depth}`
        echo "Creating the directory/subdirectory $Create_Directory"
        mkdir -pv "$Create_Directory"
    fi
done

Directory_List=`find "${Source_Dir}" -type d -exec sh -c 'ls -tr -1 "{}" | sort | egrep -iq "*.(jpg|png|flac)$"' ';' -print`
oIFS=$IFS
IFS=$'\n'
for directories in $Directory_List
    do
    echo "Directories coming from the source : $directories"
    typeset -i directories_depth
    directories_depth=`echo $directories | grep -oi "\/" | wc -l`
    echo "Number of sub-directories to be checked: $Source_Dir_Depth"
    typeset -i number_of_directories_depth
    number_of_directories_depth=$directories_depth+1
    for depth in `seq 2 $number_of_directories_depth`
        do
        Source_Tree=`echo ${Source_Dir} | cut -d'/' -f-${depth}`
        Subdirectory_Tree=`echo ${directories} | cut -d'/' -f-${depth}`
        Subdirectory_Remaining_Tree=`echo ${directories} | cut -d'/' -f${depth}-`
        echo "source tree : $Source_Tree"
        echo "source tree : $Subdirectory_Tree"
        if [[  $depth -le $Source_Dir_Depth && $Source_Tree = $Subdirectory_Tree ]]
        then
            echo "Common Directory, skipping ($Subdirectory_Tree)"
            continue
        else
            export Targetecho=$(echo $Target_Dir | sed -e 's/\r//g')
            export Destination_Directory=${Targetecho}${Subdirectory_Remaining_Tree}
            echo "Destination directory is : $Destination_Directory"
            export Sub_directories_depth=`echo $Destination_Directory | grep -oi "\/" | wc -l`
            echo "Total destination depth : $Sub_directories_depth"
            echo "Now we are checking target directory structure"
        fi
        break
        done
    echo "Gettin into the new loop to verify/create target structure"
    typeset -i number_of_Sub_directories_depth
    number_of_Sub_directories_depth=$Sub_directories_depth+1
    for subdepth in `seq 2 $number_of_Sub_directories_depth`
        do
        Target_Subdirectory_Tree=`echo ${Destination_Directory} | cut -d'/' -f-${subdepth}`
        if [[ $subdepth < $number_of_Sub_directories_depth && -d "$Target_Subdirectory_Tree" ]]
        then 
            echo "Directory already exists in the destination ($Target_Subdirectory_Tree)"
        elif [[ $subdepth < $number_of_Sub_directories_depth && ! -d "$Target_Subdirectory_Tree" ]]
        then
            echo "Creating the path in the destination ($Target_Subdirectory_Tree)"
            mkdir -pv "$Target_Subdirectory_Tree"
        elif [[ $subdepth -eq $number_of_Sub_directories_depth ]]
        then
            if [[  ! -d "$Destination_Directory" ]]
            then            
            echo "Creating Directory: $Destination_Directory"
            mkdir -pv "$Destination_Directory"
            fi
            echo "Directory already exists in the destination ($Destination_Directory)"
#Flac file processing starts here once the directory is found
            Flac_File_List=`(shopt -s nocaseglob ; ls -tr "${directories}"/*.flac | sort)`
            echo "List of files in $directories :"
            echo $Flac_File_List
            for flac_files in $Flac_File_List
            do
                echo "files : $flac_files"
                typeset -i flac_file_depth
                flac_file_depth=`echo $flac_files | grep -oi "\/" | wc -l`
                flac_file_depth=$flac_file_depth+1
                echo "flac_file_depth : $flac_file_depth"
                Flac_File_Name=`echo ${flac_files} | cut -d'/' -f${flac_file_depth}`
                echo "Flac_File Name : $Flac_File_Name"
                Destination_File=${Destination_Directory}'/'${Flac_File_Name}
                echo "will convert $Flac_File_Name from $flac_files to $Destination_File"
                yes | ffmpeg  -i "$flac_files" -vf "crop=((in_w/2)*2):((in_h/2)*2)" -c:a alac "${Destination_File%.flac}.m4a"
            done
#Artwork file processing starts here once the directory is found
            Art_File_List=`(shopt -s nocaseglob ; ls -tr "${directories}"/*.{png,jpg} | sort)`
            echo "List of files in $directories :"
            echo $Art_File_List
            for art_files in $Art_File_List
            do
                echo "files : $art_files"
                typeset -i art_file_depth
                art_file_depth=`echo $art_files | grep -oi "\/" | wc -l`
                art_file_depth=$art_file_depth+1
                echo "file_depth : $art_file_depth"
                Art_File_Name=`echo ${art_files} | cut -d'/' -f${art_file_depth}`
                echo "File Name : $Art_File_Name"
                Destination_File=${Destination_Directory}'/'${Art_File_Name}
                echo "will copy $Art_File_Name from $art_files to $Destination_File"
                cp "$art_files" "$Destination_File"
            done
        else
            echo "did nothing!!!"
        fi
        done
done
IFS=$oIFS

随意更改,改进,分发。卡格拉尔

4

1 回答 1

1

试试这个:

#!/bin/bash

src_dir="in"
dst_dir="out"

find ${src_dir} -type f -print0|while IFS= read -r -d '' src_file; do
        dst_file=${src_file/$src_dir/$dst_dir}

        echo "src_file=${src_file} dst_file=${dst_file}"
        mkdir -pv `dirname $dst_file`
        # use above variables and run convert command with it here
done

要测试它是如何工作的:

mkdir in out
cd in
mkdir 1 2 3
find . -type d -exec touch {}/foo {}/bar {}/baz \;
cd ..
./run_my_script.sh

现在你只需要附加你的转换函数/脚本/命令/任何东西并改进它以读取src_dirdst_dir从命令行(我会推荐man bash- > getopts

于 2014-12-08T00:20:43.743 回答