findコマンドの拡張パラメータの最初の文字を取得します。

findコマンドの拡張パラメータの最初の文字を取得します。

画像が多すぎて最初の3文字+ .jpg拡張子と一致するフォルダに入れたいです。

4_1_0002.pngそのため、ファイル(4_1で始まるすべてのファイル)をインポートして4_1_.jpgフォルダに入れたいと思います。同様に、ファイル(4_2で始まるすべてのファイル)をインポートしてフォルダ4_2_0002.pngに入れたいと思います。4_2_.jpg

ソートしたいファイルはすべて1つの巨大なフォルダにあります。 findコマンドを使用しようとしていますが、{}拡張パラメータから最初の3文字を抽出する方法がわかりません。

find . -type f -ok echo mv {} "path/first3char.jpg" \;

ここに画像の説明を入力してください。

ここに画像の説明を入力してください。

答え1

ファイル名を簡単に変更できるツールがあります。たとえば、Perlのrename実装では、通常は次の名前を使用しますprename

prename '$dir = substr($_,0,3); mkdir $dir; $_ = "$dir/$_"' *.jpg

ディレクトリがすでに存在する場合は、次のように単純化できます。

prename 's!(...)!$1/$1!' *.jpg

prenameたとえば、ディストリビューションに 1 つが含まれていない場合は、1 つをインストールします。Unicode::戦いまたはファイル::名前の変更

findファイルはすべて同じディレクトリにあるため、ここでは役に立ちません。ただし、コマンドラインが長すぎるため、エラーが発生する可能性があります。findこの問題を解決する 1 つの方法を使用できます。

find -maxdepth 1 -name '*.jpg' -exec prename 's!(...)!$1/$1!' {} +

または、次を実行します。扱いにくいbashの代わりに活用してくださいzmv機能

autoload zmv        # you can put this in ~/.zshrc
mkdir_mv () {
  mkdir -p -- $2:h
  mv -- $1 $2
}
zmv -p mkdir_mv '(???)*.jpg' '$1/$f'

ディレクトリがすでに存在する場合は、次のものを使用できます。

zmv '(???)*.jpg' '$1/$f'

答え2

src="/pathto/large_folder"
dest="/tmp/3chars"

mkdir -p "$dest" || exit 1

cd "$src" && \
find . -type f -name '???*' -exec sh -c '
   for f
   do
      b=${f##*/}
      d=${b%"${b#???}"}_.jpg
      [ -d "$dest/$d" ] || mkdir -p "$dest/$d"
      mv "$f" "$dest/$d/."
   done
' x {} +

関連情報