検索を使用してファイルを移動するときにディレクトリ構造を維持する

検索を使用してファイルを移動するときにディレクトリ構造を維持する

定義された古いファイルをソースディレクトリからターゲットディレクトリに移動するために、次のスクリプトを作成しました。それは非常にうまく動作します。

#!/bin/bash

echo "Enter Your Source Directory"
read soure

echo "Enter Your Destination Directory"
read destination 

echo "Enter Days"
read days



 find "$soure" -type f -mtime "-$days" -exec mv {} "$destination" \;

  echo "Files which were $days Days old moved from $soure to $destination"

スクリプトはファイルをうまく移動し、ソースサブディレクトリでもファイルを移動しますが、ターゲットディレクトリにサブディレクトリを作成しません。このアドインを実装したいと思います。

例えば

/home/ketan     : source directory

/home/ketan/hex : source subdirectory

/home/maxi      : destination directory

このスクリプトを実行すると、16進ファイルもmaxiディレクトリに移動しますが、maxiディレクトリに同じ16進ファイルを作成し、そのファイルを本番環境で同じ16進数に移動する必要があります。

答え1

find指定されていることを知っているがrsync

はい

同じディレクトリ構造を持つイメージファイル(ソースは同じままです):

rsync -axuv --progress Source/ Target/

同じディレクトリ構造にファイルを移動します(ソースから削除して空のディレクトリを削除します)。

rsync -axuv --prune-empty-dirs --remove-source-files --progress Source/ Target/

特定のファイル形式でファイルを移動する(はい):

rsync -rv --include '*/' --include '*.js' --exclude '*' --prune-empty-dirs Source/ Target/

find高度な検索で生成されたファイルを移動する:

cd "$source" &&
  rsync -av --remove-source-files --prune-empty-dirs --progress --files-from <(find . -type f -mtime -$days) . "$destination"

ファイル削除ガイド

rsyncターゲットディレクトリにソースディレクトリをミラーリングさせ、ソースに存在しなくなったターゲットのファイル(たとえば、、、など--delete-before--delete-after--delete-during削除するオプションがあります--delete-delay

また、ターゲットディレクトリ(例:--remove-source-files

これはユースケースによって異なり、処理方法はユーザーによって異なります。

メモ:Sridar Sarnobatが指摘したように、rsyncしたいディレクトリへのシンボリックリンクを持つディレクトリをrsyncすると、そして--remove-source-files`を使用すると、データが失われる可能性があります。

答え2

mv /home/ketan/hex/foo /home/maxirun以外の生成されたパスに基づいてターゲットディレクトリを変更する必要がありますfind。まず、ソースディレクトリに変更しますfind .。作成するすべてのプロジェクトの前にターゲットディレクトリを追加するだけですfindfind … -exec接続を実行し、必要に応じてターゲットディレクトリを作成するには、コマンドでシェルを実行する必要があります。

destination=$(cd -- "$destination" && pwd) # make it an absolute path
cd -- "$source" &&
find . -type f -mtime "-$days" -exec sh -c '
  mkdir -p "$0/${1%/*}"
  mv "$1" "$0/$1"
' "$destination" {} \;

$destination特殊文字が含まれる場合、引用の問題を回避するために、シェルスクリプトで特殊文字を置き換えることはできません。内部シェルに到達するために環境にエクスポートするか、パラメータとして渡すことができます(私がやった方法です)。呼び出しをグループ化して実行時間を節約できますsh

destination=$(cd -- "$destination" && pwd) # make it an absolute path
cd -- "$source" &&
find . -type f -mtime "-$days" -exec sh -c '
  for x do
    mkdir -p "$0/${x%/*}"
    mv "$x" "$0/$x"
  done
' "$destination" {} +

または、zshで次のものを使用できます。zmv機能、そして.そしてm グローバル予選正しい日付範囲内の通常のファイルのみを一致させます。必要に応じて、mvまずターゲットディレクトリを作成する代替関数を渡す必要があります。

autoload -U zmv
mkdir_mv () {
  mkdir -p -- $3:h
  mv -- $2 $3
}
zmv -Qw -p mkdir_mv $source/'**/*(.m-'$days')' '$destination/$1$2'

答え3

2つのfind(1)インスタンスを使用してこれを実行できます。

常に cpio(1) があります。

(cd "$soure" && find … | cpio -pdVmu "$destination")

cpioのパラメータを確認してください。私が与えたもの

答え4

返されたファイルの絶対パスをターゲットパスに追加するだけfindです。

find "$soure" -type f -mtime "-$days" -print0 | xargs -0 -I {} sh -c '
    file="{}"
    destination="'"$destination"'"
    mkdir -p "$destination/${file%/*}"
    mv "$file" "$destination/$file"'

関連情報