4番目のディレクトリ名をツリーに入れる方法を知る必要があります。このディレクトリvarはループ操作中に変更されるため、このディレクトリ構造はループの実行時に常に更新されるため、更新して最新の状態に保つ必要があります。
/dir 1/dir 2/dir 3/dir 4/dir 5/ 他の場所で使用するには、4 番目のディレクトリの名前を var に入れる必要があります。
私はループを使用し、このように抽出します。
#!/bin/bash
working_dir="/media/data/temp1"
script_dir="$HOME/working"
find "$working_dir" -type f -name "*.*" | while [ $xf -lt $numberToConvert ] ;
do read FILENAME;
j=$FILENAME
xpath=${j%/*}
xbase=${j##*/}
xfext=${xbase##*.}
xpref=${xbase%.*}
path1=${xpath}
pref1=${xpref}
ext1=${xfext}
echo
echo
echo "xpath is -> "$xpath""
echo "xbase is -> "xbase""
echo "xfext is -> "$xfext""
echo "xpref is -> "$xpref""
echo "path is -> "$path1""
echo "pref is -> "$pref1""
echo "ext is -> "$ext1""
echo
getme="$(basename "$working_dir/")"
echo "GET ME "$getme""
echo
//Code that does stuff to files in dir's after the 4th Dir
// is here but hidden
let xf++
done
これらの結果はすべて次のとおりです。
xpath is -> /media/data/temp1/Joe Jackson - The Ultimate Collection/CD2
xbase is -> xbase
xfext is -> mp3
xpref is -> Jumpin' Jive Live - Joe Jackson
path is -> /media/data/temp1/Joe Jackson - The Ultimate Collection/CD2
pref is -> Jumpin' Jive Live - Joe Jackson
ext is -> mp3
GET ME temp1
basename は、次の 4 番目のディレクトリではなく、3 番目のディレクトリを返します。これは、/ temp1 / ... /とCDの間のディレクトリ名を取得するために必要です。
/media/data/temp1/Joe Jackson - The Ultimate Collection/CD2
スクリプトが完了すると、Joe Jackson ...ディレクトリ名が変更され、別の名前の別の4番目のディレクトリに移動するため、それを更新して現在の4番目のディレクトリ名のみを取得できるようにする必要があります。
私が必要なのはこんなものだけです。
4thDirNameIs=${code goes here}
5、3、または他のディレクトリまたはファイル名ではなく、ディレクトリ構造のレベル4。
タイトルはすべてを教えてくれます。 Enterはキーワードであり、ディレクトリに入るにはディレクトリの外になければならない4番目のディレクトリ名です。
今回は十分に明確になってほしいです。
答え1
ファイルが$FILENAME
。この例では手動で設定しました。
FILENAME="/media/data/temp1/Joe Jackson - The Ultimate Collection/CD2/Jumpin' Jive Live - Joe Jackson.mp3"
シェルの使用:
$ dir=${FILENAME#*/*/*/*/}; echo ${dir//\/*} Joe Jackson - The Ultimate Collection
ここでは、最初の4つのスラッシュを削除し、4番目のディレクトリとファイル名を保持してからファイル名を削除します。
シェルと
basename
:$ dir=${FILENAME#*/*/*/*/}; basename "$dir" Jumpin' Jive Live - Joe Jackson.mp3
basename
最後のステップについてのみ上記とほぼ同じアイデアです。Perlで分析してみてください:
$ エコー "$FILENAME" #(.? /){4}(.?)/.*#$2#' ジョー・ジャクソン - Ultimate Collection
正規表現は、ゼロ個以上の文字が4回繰り返された項目とスラッシュが続き、次のスラッシュがあるすべての項目とその他のすべての項目を一致させます。括弧を使用すると、一致するパターンをキャプチャできるため、すべてを2番目のパターン(ディレクトリ名)に置き換えます。
あるいは、行をslapehsの配列に分割し、5番目のフィールドを印刷することもできます(5番目のフィールドは、変数が最初のフィールドを空にし
/
始めるためです)。$ echo "$FILENAME" | perl -F"/" -lane 'print $F[4]' Joe Jackson - The Ultimate Collection
解析
awk
:$ echo "$FILENAME" | awk -F"/" '{print $5}' Joe Jackson - The Ultimate Collection
同じ考えですが
awk
。
答え2
minデプスと最大深度パラメータを使用して、そのパラメータを見つけてawkにパイプすることができます。
find $someBaseDir -type d -mindepth 4 -maxdepth 4 | awk -F'/' '{ print $NF }'
各結果に対して何かを行うには、forループに入れることができます。
たぶん、次のようなものがあります。
for fdir in $(find $Base -type d -mindepth 4 -maxdepth 4 | awk -F'/' '{ print $NF }'); do DO_STUFF_WITH $fdir done
答え3
Jongの答えは非常に似ていますが、引数はmindepth
コマンドmaxdepth
の起動ディレクトリに関連していますfind
。必要なディレクトリ構造の最初の3つの部分がすでに存在するという事実も考慮することができます。これからは本当に行く必要があります。一つ必要な情報を入手するには、より深く進んでください。これには、ディレクトリ内の他のすべてのエントリを除外する追加の利点があります。とは別にあなたが望むもののために。次のコードスニペットは、事前定義された変数、$working_dir
パラメータ-mindepth
、およびパラメータ拡張を使用して、/media/data/temp1の「4深さ」のすべてのディレクトリを検索します。-maxdepth
find
for my_dir in $(find ${working_dir} -mindepth 1 -maxdepth 1 -type d -print)
do
DirName=${my_dir##${working_dir}/}
## loop through, working on the 4th directory list
## one directory at a time
. . .
done
FWIW、変数名を数字で始めてはいけません。 BASHなどの一部のシェルは、それを位置パラメータへの参照として挿入しますが、期待どおりに機能しません(たとえば、存在しても存在しなくてもよい$4thDirNameIs
位置パラメータに展開してから、「thDirNameIs」が来ます)。$4
答え4
この質問にご協力いただきありがとうございます。これが私が思いついた答えです。ルート/フォルダから4番目のディレクトリまですべてのディレクトリを見つけ、一度に1つのディレクトリに移動してすべてのファイルをインポートしてアーカイブします。循環の最も内側のレベルで動作します。選択したファイルがすべて完了したら、次のベースの4番目の場所に移動し、そのサブディレクトリも同じことを行います。
作業するディレクトリの数と場所を制御するのは、ユーザー入力に依存します。
#!/bin/bash
typeset -i f d control DirCountDn fileCount dirCount
let f=0 d=0 control=1 DirCountDn=0 fileCount=0 dirCount=0
amount_of_dir_to_work_on="4"
working_dir="/media/data/music"
#CONTROL LOOP keeps it one dir at a time
for i in 1
do
# get all of the names of the base dir to change name a var containing ampunt of basenamedir in last place here
find "$working_dir" -mindepth 1 -maxdepth 1 -type d | while [ $DirCountDn -lt $amount_of_dir_to_work_on ] ;
do read DIRNAME;
echo "$DIRNAME"
echo
MAXMP3="$(find "$DIRNAME" -type f -name "*.mp3" | wc -l)"
echo;echo;echo
echo "amount of mp3 "$MAXMP3" in "$DIRNAME""
echo;echo;echo;echo
find "$DIRNAME" -type f -name "*.mp3" | while [ $fileCount -lt $MAXMP3 ] ;
do read FILENAME;
echo;echo
echo "***************************************"
echo "FILENAME is "$FILENAME""
DIRNAME=${DIRNAME#*/*/*/*/}
DIRNAME=${DIRNAME//\/*}
echo "DIRNAME is "$DIRNAME""
echo
echo " work each mp3 file in incurments until Dir is finised will all mp3 files"
echo "rename dir then make provisons to move it somewhere else"
echo "then move it - go onto nest directory within the tree root dir"
echo "amount of filename "$fileCount""
echo "******************************************"
let fileCount++
echo "count on file names "$fileCount""
echo;echo
done
let dirCount++
echo "Dir Count "$dirCount""
echo;echo
let DirCountDn++
#reset fileCount for next dir
let fileCount=0
done
echo "this is i -> "$i""
done
# returns sub dir only one deep and not working dir
#find /dir/dir/dir/getThisOneNameOnly -mindepth 1 -maxdepth 1 -type d -exec basename {} \;