異なるサブフォルダに似た名前のファイルがたくさんある(ただし、すべてパターンに従っている)という状況があります
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 ]]
- もし"コピー"ファイルは最新のものです - それをオリジナル1つ(作るオリジナル) とmv "$0" "$p/$main_bn"
- そうでなければオリジナルファイルは最新のもので、「コピー「ファイル」
rm "$0"
-nt
または、ファイル テスト演算子 ( -が より最近変更されたかどうか、またはが存在しないかを[ newerfile –nt olderfile ]
チェック)を使用すると、少し短くなります。newerfile
olderfile
newerfile
olderfile
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
ot ファイル) を含め、隠しディレクトリに降ります。.
: のみ含む通常ファイル (ディレクトリ、FIFO、デバイス、シンボリックリンクなし...)$file:h
:頭ファイル(ディレクトリ部分)のcsh
$file:t
:しっぽ(ファイル名部分)${var/pattern/replacement}
、ここでは代替品はありません[[ ! -f $base || -L $base ]] ||...
安全策として、非通常のファイルまたはシンボリックリンク (通常のファイルを指している場合でも) をスキップします。[ $file -nt $base ]
:$file
最後に変更された場合はtrueを返します後$base
(または$base
アクセスできない場合は、上記のチェックに従っても発生しないはずです)。