似た名前のファイルを探す、最も古いファイルを削除し、最新のファイル名を変更する

似た名前のファイルを探す、最も古いファイルを削除し、最新のファイル名を変更する

異なるサブフォルダに同じ名前のファイルがたくさんある状況が発生しました(ただし、すべて特定のパターンに従いました)。

file1
file1 (Copy)
/folder1/file2.txt
/folder1/file2 (Copy).txt
/folder1/file3.png
/folder1/file3 (Copy).png

各ファイルはコピーと同じフォルダにあり、名前の(Copy)末尾にあることを除いて、拡張子は同じです。

file1 (Copy)これらすべてのファイルをインポートし、最も古いファイルを削除してから最終的にファイル名を変更する必要がある場合(file1サフィックスの削除など)、ファイル名を変更したいと思います。(Copy)

使用しようとしていますが、find最もmv近いものを移動するようにどう言うべきかわかりません。

答え1

拡大するfind+bashソリューション(GNU実装も必要ですstat):

find . -type f -name "* (Copy).*" -exec bash -c 'p="${0%/*}"; bn="${0##*/}"; 
        main_bn="${bn/ (Copy)/}"; 
        if [ -f "$p/$main_bn" ]; then 
           t_copy_file=$(stat -c %Y "$0"); t_main_file=$(stat -c %Y "$p/$main_bn"); 
           if [[ $t_copy_file -gt $t_main_file ]]; then 
               mv "$0" "$p/$main_bn"; 
           else
               rm "$0"; 
           fi; 
        fi' {} \;

  • p="${0%/*}"- デフォルトの名前が切り捨てられたファイルパス/パス
  • bn="${0##*/}"- ファイルのデフォルト名
  • main_bn="${bn/ (Copy)/}"(Copy)- インポートするには、デフォルト名から部分文字列を削除します。メイン/パブリック基本名
  • if [ -f "$p/$main_bn" ]- もしメイン/オリジナルファイルが存在します(シンボリックリンクの確認後に通常のファイルとして確認されます)。
    • t_copy_file=$(stat -c %Y "$0")- 最後に変更された時間を確認してください。「コピー」文書
    • t_main_file=$(stat -c %Y "$p/$main_bn")- 最後に変更された時間を取得します。オリジナル文書
    • if [[ $t_copy_file -gt $t_main_file ]]- もし「コピー」ファイルが最近です - 次へオリジナルえ(作ってみてください)オリジナル)とmv "$0" "$p/$main_bn"
    • そうでなければオリジナルファイルが最新です。 '削除してください。コピー「文書とrm "$0"

-ntまたは、ファイルテスト演算子を使用してより短いもの( - 後で変更されたか、存在するが存在しないことを[ new­er­file –nt olderfile ]確認):newerfileolderfilenewerfileolderfile

find . -type f -name "* (Copy).*" -exec bash -c 'p="${0%/*}"; bn="${0##*/}"; 
        main_bn="${bn/ (Copy)/}"; 
        if [ -f "$p/$main_bn" ]; then 
           if [ "$0" -nt "$p/$main_bn" ]; then 
               mv "$0" "$p/$main_bn"; 
           else
               rm "$0"; 
           fi; 
        fi' {} \;

答え2

使いやすくなりますzsh

setopt extendedglob # best in ~/.zshrc
for file (./**/?*" (Copy)"*(ND.)) {
  base=$file:h/${${file:t}/" (Copy)"}}
  [[ ! -f $base || -L $base ]] ||
    if [ $file -nt $base ]; then
      mv $file $base
    else
      rm -f $file
    fi
}

ファイルがないことをまず確認することをお勧めしますfile (Copy) (Copy).txt

  • **/: すべてのレベルのサブディレクトリ
  • N:空のボール一致するものがない場合は、エラーではなく空の状態に展開されます。
  • D:隠しファイル(Dまたはファイル)を含め、隠しディレクトリに配置します。
  • .:のみ含む定期的なファイル(ディレクトリ、fifo、デバイス、シンボリックリンクなし...)
  • $file:h:ファイル(ディレクトリ部分)、例:csh
  • $file:t:(ファイル名部分)
  • ${var/pattern/replacement}、ここに代替品はありません。
  • [[ ! -f $base || -L $base ]] ||...保護措置として、フレームに縛られないファイルやシンボリックリンク(通常のファイルを指している場合でも)をスキップします。
  • [ $file -nt $base ]$file:最後に変更された場合はtrueを返します。後ろに $base(または$base上記の確認後に発生してはならないアクセシビリティ)。

関連情報