ディレクトリが常に同じでない場合は、ディレクトリ内の各ディレクトリ名から変数を生成するループを作成できますか?

ディレクトリが常に同じでない場合は、ディレクトリ内の各ディレクトリ名から変数を生成するループを作成できますか?

特定のディレクトリのすべてのサブフォルダをインポートし、別のディレクトリにサブフォルダを作成し、新しく作成されたサブフォルダにサブフォルダを作成するSynology DS 1019 +で実行されるスクリプトを作成しています。別の場所にあるすべての.mkvファイルへのハードリンク。しかし、サブフォルダがすでに2番目の場所にある場合は、ハードリンクを作成したいと思います。

私のファイルの性質のため、そのフォルダ内のフォルダ構造とファイルは、このスクリプトが使用されるインスタンスごとに異なります。各ループが場所Aの次のフォルダを取得し、各サブフォルダに対して(そのサブフォルダ内のファイルに対して)mkdirとハードリンク操作を実行するようにこのスクリプトループを作成する方法はありますか?

これが私が現在持っているものです:

#! /bin/bash

echo "Enter Movie Collection:"
read MOVIE_DIR
echo "Enter Bonus Feature Disc: "
read BONUS_DIR

cd "/volume1/Plex/Movies/$MOVIE_DIR/"

for dir in */.; do

    if [[ ! -e "$dir"/*/ ]]; then
        mkdir "$dir"/*/
    fi

    if [[ ! -d "$dir"/*/ ]]; then
        ln /volume1/Plex/"Bonus Feature Discs"/$BONUS_DIR/*/*.mkv -t ./"$dir"/*/.
    fi
done

私はループ、特にネストされたループの経験がないので、この問題をどこから始めるべきかわかりません。現在の場所Aのフォルダがまだ存在しない場合は、場所Bにコピーするか、場所Aのフォルダ内のファイルをハードリンクするのではなく、場所Bのフォルダを場所Bのホームディレクトリ(例:私のテストでは、「TEST 1」はハードリンクです。 TEST.mkvを含む"featurette"フォルダをインポートする代わりに、"TEST 1"に空のジャンクデータフォルダをインポートします。

私はデフォルト名とディレクトリ名を試しましたが、ディレクトリ内の各フォルダを繰り返すようにループを作成する方法が見つかりませんでした。私も試しました。cd /the/directory/path/ "${PWD##*/}"

編集:この記事を投稿して数時間で解決策を見つけました。上記のコードは、不特定領域が多すぎて何も起こらないため、まったく論理的に理解されていません。結局最初からやり直さなければなりませんでした。これは私が何をすべきかを正確に実行するコードです。これを行う最もエレガントな方法ではないかもしれませんが、私が実行したテストによると十分にうまくいきます。

#! /bin/bash

#Ask the user to input the directories of both the bonus disc's files and where the movies are located that the bonus disc's contents will be needed.
echo "Enter the name of the Movie Collection and press [ENTER]: "
read MOVIE_DIR
echo "Enter the name of the Bonus Feature Disc and press [ENTER]: "
read BONUS_DIR


#This goes to the location of the bonus disc specified by the end user. I believe this part is necessary for creating the text document below, but it might not be.
cd "/volume1/Plex/Bonus Feature Discs/$BONUS_DIR/" || return

#This creates a text document that has each directory within the specified Bonus Disc directory as a separate line  
    ls -d -- */ >> /volume1/Plex/"Bonus Feature Discs"/output.txt
    echo ls  -d -- */


#This goes to the movie directory specified by the end user. This cd is definitely required
cd "/volume1/Plex/Movies/$MOVIE_DIR/" || return


#the for loop loops through every movie that resides in the movie collection folder
 for dir in *; do

    #this while loop reads the text document and will use each line from the document as a variable.
    while IFS=' ' read -r line; do
        name="$line"

        #A directory with the name of the line of the text document will be created in each movies directory only if it doesn't already exist
        mkdir -p "$dir/$name"

        #this will create the hard links to every single video that resides in the folders within the bonus features disc into the corresponding folders for each movie
        if [[ ! -e "/volume1/Plex/Movies/$MOVIE_DIR/$name" ]]; then 
            ln "/volume1/Plex/Bonus Feature Discs/$BONUS_DIR/$name"*.mkv -t ./"$dir/$name"
        fi

    done < "/volume1/Plex/Bonus Feature Discs/output.txt"
 done

echo "Linking Completed"
echo $dir

#finally, once all the work is complete, the script will delete the text document that is no longer needed
rm "/volume1/Plex/Bonus Feature Discs/output.txt"

ベストアンサー1

を使用し、すべてのディレクトリの作成を含む(ファイルがない場合でも)、ディレクトリ内または下のすべてのファイルをディレクトリにハードリンクするとしますrsync.mkvsourcetarget.mkv

rsync --archive --link-dest="$PWD/source" \
    --include='*/' \
    --include='*.mkv' \
    --exclude='*' \
    source/ target

--archive()オプションはファイルメタデータを-a保存しrsync、ディレクトリの再帰コピーをトリガします。このオプションは、既存のファイルをハードリンクするためのディレクトリを--link-dest提供します。このオプションはディレクトリとファイルを選択しますが、最後のオプションは選択されていない項目を無視します。rsynctarget--include.mkv--exclude--include

で作成できる空のディレクトリを削除するには、次のコマンドをtarget使用できます。find

find target -type d -empty -delete

...テストとタスクをfind実装するとします。-empty-delete

例:

source
|-- dir1
|   |-- file1.mkv
|   |-- file1.txt
|   |-- file2.mkv
|   `-- file2.txt
|-- dir2
|   |-- file1.mkv
|   |-- file1.txt
|   |-- file2.mkv
|   `-- file2.txt
|-- dir3
|   |-- file1.mkv
|   |-- file1.txt
|   |-- file2.mkv
|   `-- file2.txt
`-- dir4
    `-- file1.doc

上記のコマンドをrsync実行すると、target次のようになります。

target
|-- dir1
|   |-- file1.mkv
|   `-- file2.mkv
|-- dir2
|   |-- file1.mkv
|   `-- file2.mkv
|-- dir3
|   |-- file1.mkv
|   `-- file2.mkv
`-- dir4

ファイルがハードリンクされていることを示します(同じinode番号、リンク数2)。

$ ls -l -i source/dir1/file1.mkv target/dir1/file1.mkv
3118217 -rw-r--r--  2 kk  kk  0 Apr 10 17:03 source/dir1/file1.mkv
3118217 -rw-r--r--  2 kk  kk  0 Apr 10 17:03 target/dir1/file1.mkv

空のディレクトリを削除します。

$ find target -type d -empty -delete
$ tree target
target
|-- dir1
|   |-- file1.mkv
|   `-- file2.mkv
|-- dir2
|   |-- file1.mkv
|   `-- file2.mkv
`-- dir3
    |-- file1.mkv
    `-- file2.mkv

おすすめ記事