200を超えるサブディレクトリ「映画名(年)」を含む「New Movies」ディレクトリがあります。サブディレクトリ「映画名(年)」には、ビデオファイル(avi / mkv)と関連する複数のjpg / xmlファイルが含まれています。
少なくとも180日以上経過したビデオファイルを含むすべてのディレクトリを別のディレクトリに移動する必要があります。
たとえば、
新しい映画/映画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
移動するかどうかにかかわらず、「新しい映画」の下に含まれるすべてのディレクトリに移動します。
答え1
-exec mv
現在確認しているディレクトリを確認しないでくださいfind
。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
項目を区切るにはnull文字を使用してください。これは、ファイル名に改行文字が含まれないようにするためです。xargs
パイプラインから入力を収集し、追加された入力パラメータを使用して実行します。-0
入力が改行区切りではなくヌル区切りとして予想されるように 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
システムコールを使用してサブディレクトリの1つに移動しますchdir(subdirname)
。find
フィルタを通過した動画ファイルを探します。find
mv
指定されたパラメータを使用して実行されます。mv
ディレクトリをに移動します/mnt/user/Movies
。find
システムコールを使用して親ディレクトリに戻ると、コールchdir(..)
は/mnt/user/Movies
代わりに次のようになります。/mnt/user/New Movies/
find
前述のディレクトリが見つからず、多くのエラーが発生するため、非常に混乱しています。
この仮定は、次の質問に対する回答に基づいています。find -exec mvが最初の実行後に停止しました。find
この場合、なぜ動作が停止し、あなたの場合にエラーが発生するのかわかりません。他のバージョンがfind
説明かもしれません。
答え2
設定IFSIFS=$(echo -en "\n\b");
シェルがスペースの代わりに改行に基づいて項目を区切るようにする環境変数。
しかも-exec sh -c 'mv "${0%/*}" /mnt/user/Movies' {} \;
おかしいです。私が正しく覚えていれば、次のように簡単になります。-exec mv {} /mnt/user/Movies \;