SubDir名4の深さを抽出し、後で使用するためにVar 4に入れる方法は?

SubDir名4の深さを抽出し、後で使用するためにVar 4に入れる方法は?

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深さ」のすべてのディレクトリを検索します。-maxdepthfind

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 {} \;

関連情報