find + xargs - あるサブディレクトリから別のサブディレクトリにファイルをコピー/移動

find + xargs - あるサブディレクトリから別のサブディレクトリにファイルをコピー/移動

私のフォルダ構造は次のとおりです。

/volume1
  /photoTest
    /folderA
      /@eaDir
      /eaDir_tmp 
    /folderB
      /@eaDir
      /eaDir_tmp 
    /folder with space
      /@eaDir
      /eaDir_tmp 

私がしたいのは、各フォルダのファイルをeaDir_tmpその@eaDirフォルダにコピーすることです。

私はそれを通してそれを働かせることができました:

for a in $(find /volume1/photoTest -type d -name eaDir_tmp); do rsync -vhar --chmod=a+rwx $a/ $a/../@eaDir; done;

空白のあるフォルダをクリックするまでです。上記のスクリプトは完全なごみです。

多くのインターネット検索の最後に、私は以下を試しました。

find /volume1/photoTest -type d -name eaDir_tmp -print0 | xargs -0 rsync -vhra --chmod=a+rwx {} {}/../@eaDir

コマンドのテスト実行が問題なく機能しました。しかし、印刷後に実際のジョブが中断されました。

sending incremental file list
@eaDir/subdir1/

そしてそれに立ち往生。

ps -elf | grep rsync複数のrsyncプロセスの開始とwaitステータスを表示しますpoll_s

何が起こっているのか知っている人はいますか?解決策は何ですか?最終的にファイルを移動したいのですが、問題が発生しても邪魔にならないように、まずファイルをコピーしてみてください。

あるいは、2つのコマンドを使用して動作させることができますが、醜い部分がたくさんあります。

# first, copy all files via:    
find /volume1/photo -type d -name eaDir_tmp -exec cp -a -t {}/../@eaDir {}/. \;

# second, change file permissions:    
find /volume1/photo -type d -name @eaDir -exec chmod 777 {} -R \;

ただし、これはrsyncが実行できる操作に比べて非常に限られているだけでなく、遅くて2倍もかかります。

いくつかの背景情報:

  • フォルダの中には何が含まれていますかeaDir?より多くのフォルダとその中にあるいくつかのファイル。役に立つなら、すべてが始まる方法は次のとおりです。https://github.com/mbrrg/synology-thumbgen。作成者は既存の@eaDirフォルダを削除し、単に名前を変更することを提案しましたが、既存eaDir_tmpのフォルダに保存したいファイルが含まれているため、そうすることはできません。説明できますが、問題をさらに混乱させると思います。
  • これは私のSynology NAS DSM 6.0+内にあり、BusyBoxを実行していると思いますか?しかし、わかりません。
  • ターゲットファイルが存在する場合は、ソースファイルが最新の場合は上書きしたいと思います。そうでなければそうではありません。

答え1

find /volume1/photoTest -type d -name eaDir_tmp -prune \
    -exec sh -c 'rsync -a "$1"/ "${1%/*}/@eaDir"' sh {} ';' \
    -o -type d -name @eaDir -prune

eaDir_tmpそれから名前が。以下のすべてのディレクトリを探します/volume1/photoTest。これらの各ディレクトリに対して、次のコマンドが実行されます。

rsync -a "$1"/ "${1%/*}/@eaDir"

$1見つかったディレクトリのパス名はどこにありますか?パラメータ置換は、${1%/*}パス名の最後のコンポーネントを削除して、たとえば/volume1/photoTest/folderA/eaDir_tmp/volume1/photoTest/folderAとして使用することもできます"$( dirname "$1" )")に置き換えます。

eaDir_tmp見つかったコンテンツとディレクトリが見つかったら、@eaDir検索リストから削除してfind入力を中止します。これはで行われます-prune


承諾find-execdir

find /volume1/photoTest -type d -name eaDir_tmp -prune \
    -execdir rsync -a eaDir_tmp/ @eaDir ';' \
    -o -type d -name @eaDir -prune

関連:


使用zsh:

for dirpath in /volume1/photoTest/*/eaDir_tmp(/DN); do
    rsync -a "$dirpath"/ "$dirpath:h/@eaDir"
done

使用bash:

shopt -s dotglob nullglob
for dirpath in /volume1/photoTest/*/eaDir_tmp/; do
    rsync -a "$dirpath"/ "$(dirname "$dirpath")/@eaDir"
done

答え2

強打の使用:

for a in volume1/photoTest/*
   do 
      pushd "$a"/eaDir_tmp
      cp -u * ../@eaDir          #... or rsync --chmod...
      popd 
   done

関連情報