LAMEでmp3を変換しています。私が書いた古いスクリプトはすでに機能していますが、この機能を追加したいと思います。ファイルを削除するのではなく、既存のパスを使用すると一致するサブディレクトリを持つ新しいルートフォルダーに保存します。に。
これは、パスを取得するためにスクリプトで使用しているインターネットから取得したコードです。
c=$FILENAME
xpath=${c%/*}
xbase=${c##*/}
xfext=${xbase##*.}
xpref=${xbase%.*}
path=${xpath}
pref=${xpref}
ext=${xfext}
xpath
とpath
は、ディレクトリ構造を提供します/home/user/working-root-directory/band-folder/album-name/
その手法を使用して、これをスクリプト化して、バンドフォルダーだけを個別の変数に、アルバムフォルダーだけを個別の変数にするにはどうすればよいですか?
次に、それらを使用して、すべてのmp3をバンドアルバム順に保持して新しいフォルダーを作成し、それらを別のルートフォルダーに配置します。これにより、自分でファイルを移動する必要がなくなり、次回スクリプトを実行するときに、再度サンプリングすることはありません。これは、作業用のディレクトリパス/フォルダーには存在せず、ファイルのバックアップコピーがあるだけだからです。万一に備えて。
$c
を参照する場合、filenameの場合、ファイルへのフルパスを意味するので、このジョブは非常に簡単です。それを行うにはいくつかの方法があります。
POSIXシェルグロブとパラメーター展開だけを使用して、次のことができます。
c='/home/user/working-root-directory/band-folder/album-name/music-file.mp3'
file=${c##*/}
album=${c#*"${c%/*/"$file"}"/}
band=${c#*"${c%/*/"$album"}"/}
band=${band%%/*} album=${album%%/*}
基本的には、変数の末尾から文字列をトリミングし、変数の先頭から結果をトリミングすることで機能します。最後の行では、尾から不要な残留物が取り除かれます。おそらく、実際のデータで理解する方が簡単です。上記のスニペットをset -x
を有効にしてシェルでラップすると、これらの行に沿ってstderr
に出力されるものが表示されます。
+ c=/home/user/working-root-directory/band-folder/album-name/music-file.mp3
+ file=music-file.mp3
+ album=album-name/music-file.mp3
+ band=band-folder/album-name/music-file.mp3
+ band=band-folder
+ album=album-name
これを行うもう1つの方法は、シェルの内部フィールドセパレーターを使用して、/
境界でパス名を分割することです。
set -f; IFS=/ #disable globbing so as not to gen more filenames
set -- $c #set the Shell's arg array to split path
shift "$(($#-3))" #remove all but relevant fields
band=$1 album=$2 file=$3 #assign values
次に、いくつかのset -x
出力を示します。
+ c=/home/user/working-root-directory/band-folder/album-name/music-file.mp3
+ set -f
+ IFS=/
+ set -- '' home user working-root-directory band-folder album-name music-file.mp3
+ shift 4
+ band=band-folder
+ album=album-name
+ file=music-file.mp3
私はこの仕事のためにzsh
を雇うでしょう:
$ c='/home/user/working-root-directory/band-folder/album-name/filename.mp3'
$ echo $c:h
/home/user/working-root-directory/band-folder/album-name
$ echo $c:h:h
/home/user/working-root-directory/band-folder
$ echo $c:h:h:h
/home/user/working-root-directory
(...)
$ echo $c:t
filename.mp3
$ echo $c:h:t
album-name
$ echo $c:h:h:t
band-folder
(...)
Bashライフを使用する必要がある場合は、一時変数を使用する必要があります。
$ c='/home/user/working-root-directory/band-folder/album-name/filename.mp3'
$ x1=${c%/*}
$ echo $x1
/home/user/working-root-directory/band-folder/album-name
$ x2=${x1%/*}
$ echo $x2
/home/user/working-root-directory/band-folder
(...)
$ y1=${c##*/}
$ echo $y1
filename.mp3
$ y2=${x1##*/}
$ echo $y2
album-name
$ y3=${x2##*/}
$ echo $y3
band-folder
(...)
以前の解決策は私には非常に複雑に見えます。以下は私にとって最も簡単な解決策のようです。
Bashでファイル名文字列のディレクトリ名を取得するには
dirname "$varcontainingfilename"
Bashのファイル名文字列からファイル名のみを取得するには
basename "$varcontainingfilename"
このベースから、必要なことを簡単に実行できるはずです。
このシェルスクリプトをスクリプト/ a/b/cとして実行する例は、例として機能します。
#!/bin/sh
set -u
PATH='/bin:/usr/bin'
export PATH
filestring="$1"
fn=`basename "$filestring"`
dn=`dirname "$filestring"`
echo Original File String "$filestring"
echo Filename is "$fn"
echo directory is "$dn"
exit 0
変数を使用して「遊ぶ」ことを少し短くするには
c=/home/user/working-root-directory/band-folder/album-name/music-file.mp3
for var in file album band
do
eval "$var=\${c##*/}"
c=${c%\/${!var}}
done
echo $file $album $band
music-file.mp3 album-name band-folder
他の方法はread
コマンドを使用することです
IFS=/ read -r band album file <<< ${c#"${c%/*/*/*}"/}
Zshははるかに洗練されたソリューションです ですが、シェルでない場合は、awk
を使用できます。
printf "%s\n" "$path"
/home/user/working-root-directory/band-folder/album-name/music-file.mp3
band=$(awk -F/ '{print $(NF-2)}' <(printf "%s" "$path"))
printf "%s\n" "$band"
band-folder
album=$(awk -F/ '{print $(NF-1)}' <(printf "%s" "$path"))
printf "%s\n" "$album"
album-name
file=$(awk -F/ '{print $NF}' <(printf "%s" "$path"))
printf "%s\n" "$file"
music-file.mp3