再帰的にシンボリックリンクを作成し、1.JPGファイルが存在する場合は、1A.JPGに名前を変更します。

再帰的にシンボリックリンクを作成し、1.JPGファイルが存在する場合は、1A.JPGに名前を変更します。

私は1年間、すべての写真のシンボリックリンクを生成するシェルスクリプトを持っています。写真は他のカメラからインポートされ、サブディレクトリにあります。

f=$(pwd);
export f;
q="2015/";
z="2015_Links/";
find $q/. \( -name "*.CR2" -o -name "*.JPG" \) -execdir sh -c 'ln -s "$PWD"/$(basename {}) "$f"/"$z"/Link_$(basename {})' {} \;

一部の写真のファイル名が同じでエラーが発生します。

ln: failed to create symbolic link ‘2015_Links/Link_IMG_1588.CR2’: File exists

この場合、既存のファイルの名前を変更したいと思います。たとえばLink_IMG_1588.CR2Link_IMG_1588A.CR2

答え1

この問題に対する別の解決策が見つかりました。

各ファイル名が一意になるように(IMG番号+日付)、他のカメラの写真名を正常に変更しました(findおよび使用)。exiv2

find 2015/. \( -name "*.CR2" -o -name "*.JPG" \) -execdir sh -c 'exiv2 -r':basename:_%Y%m%d_%H_%M_%S' rename $(basename {})' {} \;

答え2

戦略:

  • 目的の宛先ファイル名が存在するかどうかをテストします。
  • その場合は、数字のサフィックスなどを追加してみ-1てください-2

その他の改善点:

  • -exec … {} +パフォーマンスを若干向上させるには、代わりに使用してください-execdir … {} \;-execdir絶対リンクを作成するため、ここでは実際にこれは必要ありません。
  • 内部シェルの代わりに使用してください$x(または$1使用に固執する場合)。絶対に使用しないでください:シェルフラグメント内でファイル名をシェルスクリプトに直接挿入するため、シェル構文で解析され、ファイル名にシェル構文で特別な意味を持つ文字が含まれていると競合が発生します。常に別々のパラメータとして渡されます。… {} \;{}{}find -exec{}

コード(テストされていません):

find "$q/." \( -name "*.CR2" -o -name "*.JPG" \) -exec sh -c '
    for x; do
      base=$0/Link_${x##*/}; base=${base%.*}; ext=${x##*.}
      if [ -e "$target.$ext" ]; then
        suffix=1;
        while [ -e "${base}-$suffix.$ext"; do suffix=$((suffix+1)); done
      fi
      ln -s -- "$PWD/${x##*/}" "$target"
    done
  ' "$PWD/$z" {} +

関連情報