200以上のサブディレクトリ「MovieName(year)」を含むディレクトリ「NewMovies」があります。サブディレクトリ「MovieName(year)」には、単一のビデオファイル(avi/mkv)といくつかの関連するjpg/xmlファイルが含まれています。
180日以上経過したビデオファイルを含むすべてのディレクトリを別のディレクトリに移動する必要があります。
例えば:
新しいMovies/Movie A(年)にはmovie.mkv、folder.jpg、movie.xmlが含まれ、すべてのファイルが存在し、そのままの状態で、同じ名前のサブディレクトリに移動したいと思います。
このサイトの他の場所を見た後、私は試しました:
cd "/mnt/user/New Movies/"
find -type f \( -name "*.avi" -or -name ".*mkv" \) -mtime +180 -exec sh -c 'mv "${0%/*}" /mnt/user/Movies' {} \;
このコマンドは、最初のサブディレクトリとすべてのファイルを新しいホームに正常に移動しますが、これ以降のすべての操作でエラーが返されます。
find: './Movie B (year)': No such file or directory
find: './Movie C (year)': No such file or directory
移動予定かどうかに関係なく、「新しい映画」の下に含まれるすべてのディレクトリを介して以下同様に続きます。
find
によって現在検査されているディレクトリを_-exec mv
_しないでください。そうすると、find
が混乱するようです。
回避策:最初にディレクトリを見つけてから移動します。
_cd "/mnt/user/New Movies/"
find -type f \( -name "*.avi" -or -name ".*mkv" \) -mtime +180 \
-printf "%h\0" | xargs -0 mv -t /mnt/user/Movies
_
説明:
-printf
_は、フォーマット文字列に従って一致を出力します。%h
_は、一致のパス部分を出力します。これは、コマンドの_"${0%/*}"
_に対応します。\0
_は、ヌル文字を使用して項目を区切ります。これは、ファイル名に改行が含まれている場合の予防策です。xargs
はパイプから入力を収集し、入力を追加して引数を実行します。-0
_は、入力が改行で区切られるのではなくnullで区切られることを期待するようにxargsに指示します。mv -t <target>
_を使用すると、すべてのソース引数を最後に追加してmv
を呼び出すことができます。これはまだ絶対に安全ではないことに注意してください。パイプバッファと組み合わせた一部の異常なスケジューラのタイミングにより、mv
がディレクトリから移動する前にfind
が実行される可能性があります。それさえ防ぐためにあなたはこのようにそれをすることができます:
_cd "/mnt/user/New Movies/"
find -type f \( -name "*.avi" -or -name ".*mkv" \) -mtime +180 \
-printf "%h\0" > dirstomove
xargs -0 mv -t /mnt/user/Movies < dirstomove
_
背景説明:
あなたのfind
で何が起こるかは次のとおりだと思います。
find
はディレクトリ_/mnt/user/New Movies/
_をトラバースします。そこにいる間、キャッシュ内の利用可能なディレクトリに注意します。find
は、システムコールchdir(subdirname)
を使用してサブディレクトリの1つに移動します。find
は、フィルターを通過するムービーファイルを検索します。find
は、指定されたパラメーターを使用してmv
を実行します。mv
はディレクトリを_/mnt/user/Movies
_に移動します。find
は、システムコールchdir(..)
を使用して親ディレクトリに戻ります。これは、_/mnt/user/Movies
_ではなく_/mnt/user/New Movies/
_を指すようになりました。find
は、前にメモしたディレクトリが見つからず、多くのエラーをスローするため、混乱しています。この仮定は、この質問への回答に基づいています: find -exec mvは最初のexecの後に停止します 。その場合、なぜfind
が機能しなくなり、エラーが発生するのかわかりません。 find
の異なるバージョンが説明かもしれません。
[〜#〜] ifs [〜#〜]環境変数をIFS=$(echo -en "\n\b");
に設定すると、シェルはスペースではなく改行に基づいてアイテムを区切ります。
さらに、この-exec sh -c 'mv "${0%/*}" /mnt/user/Movies' {} \;
は非常に奇妙です。私が間違っていない場合は、-exec mv {} /mnt/user/Movies \;
に単純化してください