以下のコードを使用して画像をフィルタリングするときは、ファイルもフィルタリングする必要があります。
例えば、IMG_0079.JPG.JPG、以下のコードを実行すると、.JPG
添付ファイルをフィルタリングできます。理由がわからないようです。
入力が正しいことを確認してください。
if [ $# != 2 ]; then echo "Usage: phar image_path archive_path" && exit; fi
宛先ディレクトリが存在しない場合、ディレクトリが作成されます。
mkdir -p $2
ファイルに必要なサフィックスを見つけてコピーして追加するステートメント
find $1 -iname IMG_[0-9][0-9][0-9][0-9].JPG -exec cp -b --suffix=.JPG {} $2 \; echo complete!
重複したドアを確認して削除します。各ファイルのmd5を比較します。
shopt -s nullglob for file in "$2"/* do md5sum=$(md5sum < "$file") echo "-- Found: $file ($md5sum)" for duplicate in "$2"/* #loop to find/remove duplicates do [ "$file" = "$duplicate" ] && continue #comparison of 2 files [ "$md5sum" = "$(md5sum < "$duplicate")" ] && rm -v "$duplicate" #removal of duplicates done done
答え1
私が正しく理解した場合、問題は次のとおりです。
find $1 -iname IMG_[0-9][0-9][0-9][0-9].JPG
.JPG.JPG
最初はファイルが見つかりませんでした。望むより:
mkdir JPG
for n in 9 8 7 6 5 4 3 2 1
do touch ./JPG/IMG_000${n}.JPG
done
find ./JPG -iname IMG_[0-9][0-9][0-9][0-9].JPG
###OUTPUT###
./JPG/IMG_0001.JPG
./JPG/IMG_0002.JPG
./JPG/IMG_0003.JPG
./JPG/IMG_0004.JPG
./JPG/IMG_0005.JPG
./JPG/IMG_0006.JPG
./JPG/IMG_0007.JPG
./JPG/IMG_0008.JPG
./JPG/IMG_0009.JPG
今私は...
for f in ./JPG/* ; do touch ${f}.JPG ; done && ls ./JPG
IMG_0001.JPG IMG_0003.JPG.JPG IMG_0006.JPG IMG_0008.JPG.JPG
IMG_0001.JPG.JPG IMG_0004.JPG IMG_0006.JPG.JPG IMG_0009.JPG
IMG_0002.JPG IMG_0004.JPG.JPG IMG_0007.JPG IMG_0009.JPG.JPG
IMG_0002.JPG.JPG IMG_0005.JPG IMG_0007.JPG.JPG
IMG_0003.JPG IMG_0005.JPG.JPG IMG_0008.JPG
find
今私たちに何が表示されるのか見てみましょう。
find ./JPG -iname IMG_[0-9][0-9][0-9][0-9].JPG
###OUTPUT###
./JPG/IMG_0001.JPG
./JPG/IMG_0002.JPG
./JPG/IMG_0003.JPG
./JPG/IMG_0004.JPG
./JPG/IMG_0005.JPG
./JPG/IMG_0006.JPG
./JPG/IMG_0007.JPG
./JPG/IMG_0008.JPG
./JPG/IMG_0009.JPG
ご存知のように、私の.JPG.JPG
ファイル名は文字列で終わらないため、[0-9]{4}.JPG
find
最初は表示されません。\*
その検索文字列の末尾に を追加すると、うまく-iname
機能します。
しかし、別の答えで述べたように、別の問題はシェルボールです。たとえば、
sh -cx 'cd ./JPG ; find . -iname IMG_[0-9][0-9][0-9][0-9].JPG'
+ cd ./JPG
+ find . -iname IMG_0001.JPG IMG_0002.JPG IMG_0003.JPG IMG_0004.JPG IMG_0005.JPG IMG_0006.JPG IMG_0007.JPG IMG_0008.JPG IMG_0009.JPG
find: paths must precede expression: IMG_0002.JPG
Usage: find [-H] [-L] [-P] [-Olevel] [-D help|tree|search|stat|rates|opt|exec] [path...] [expression]
願いより?シェルが可能な場合は、[glob]
コマンド文字列を渡す前に得られた引用符で囲まれていない角かっこ内にありますfind
。おそらく次のようになります。
find "$1" -iname 'IMG_[0-9][0-9][0-9][0-9].JPG*'
最後の点に関しては、おそらくそれほど多くの再帰ループは必要ありません。私の考えでは、古いバックアップのみを削除したい場合は、すべてをcp --suffix=.JPG -b
置き換えるための実行可能な方法になる可能性がありますshopt...
。
( dir=$2
set -- "${dir}"/*[0-9].???
while [ -e "$1" ]
do cmp "$1" "${1}.JPG" &&
rm -v "${1}.JPG" 2>&1
shift ; done
) 2>/dev/null
しかし、これが方法によってかなりの部分を最適化できることは否定できません。少し次の再帰ループ:
( dir=$2
set -- "${dir}"/*[0-9].???
while [ -e "$1" ]
do until [ -e "${1}.JPG" ]
do shift || break; done
cmp "$1" "${1}.JPG" &&
rm -v "${1}.JPG" 2>&1
${1+shift} ; done
) 2>/dev/null
私は言った少しwhile
until
ループはすべて同じパラメータセットで実行され、同じファイルを2回テストしないため、まったく同じではありません。再帰入れ子になっていても同じです。とにかく最適化は、exec
追加の手順を必要とせず、until
可能な場合はいつでもシェル組み込みにのみ依存することで構成されます。
答え2
for
あなたが言及したループで私にエラーが発生しました。しかし、角かっこにエスケープ文字を使用すると正常に動作します。したがって、私のforループは次のようになります。
find $1 -iname IMG_\\[0-9\\]\\[0-9\\]\\[0-9\\]\\[0-9\\].JPG -exec cp -b --suffix=.JPG {} $2 \;