web-dev-qa-db-ja.com

ファイル名を取得するためのディレクトリパスの削除

LAMEでmp3を変換しています。私が書いた古いスクリプトはすでに機能していますが、この機能を追加したいと思います。ファイルを削除するのではなく、既存のパスを使用すると一致するサブディレクトリを持つ新しいルートフォルダーに保存します。に。

これは、パスを取得するためにスクリプトで使用しているインターネットから取得したコードです。

 c=$FILENAME
 xpath=${c%/*} 
 xbase=${c##*/}
 xfext=${xbase##*.}
 xpref=${xbase%.*}
 path=${xpath}
 pref=${xpref}
 ext=${xfext}

xpathpathは、ディレクトリ構造を提供します/home/user/working-root-directory/band-folder/album-name/

その手法を使用して、これをスクリプト化して、バンドフォルダーだけを個別の変数に、アルバムフォルダーだけを個別の変数にするにはどうすればよいですか?

次に、それらを使用して、すべてのmp3をバンドアルバム順に保持して新しいフォルダーを作成し、それらを別のルートフォルダーに配置します。これにより、自分でファイルを移動する必要がなくなり、次回スクリプトを実行するときに、再度サンプリングすることはありません。これは、作業用のディレクトリパス/フォルダーには存在せず、ファイルのバックアップコピーがあるだけだからです。万一に備えて。

6
uxserx-bw

$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
8
mikeserv

私はこの仕事のために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

(...)
2
jimmij

以前の解決策は私には非常に複雑に見えます。以下は私にとって最も簡単な解決策のようです。

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
2
mdpc

変数を使用して「遊ぶ」ことを少し短くするには

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%/*/*/*}"/}
2
Costas

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
1
jasonwryan