次のディレクトリ構造があります。
.
├── event-a
│ ├── album-a
│ │ ├── a.jpg
│ │ └── x.png
│ └── album-b
│ ├── a.jpg
│ ├── x.png
│ └── y.gif
└── event-b
├── album-x
│ ├── a.jpg
│ └── x.png
└── album-y
├── a.jpg
├── x.png
└── y.gif
2番目のレベルの各サブフォルダ(album-foo
例では名前付け)について、ファイルを名前で並べ替え、拡張子に関係なく連続パディング番号に名前を変更したいと思います。これらのフォルダにはJPG、PNG、またはGIFイメージを含めることができ、すべてのファイル拡張子を保持する必要があります。
したがって、この場合は次のようなものを得たいと思います。
.
├── event-a
│ ├── album-a
│ │ ├── 01.jpg
│ │ └── 02.png
│ └── album-b
│ ├── 01.jpg
│ ├── 02.png
│ └── 03.gif
└── event-b
├── album-x
│ ├── 01.jpg
│ └── 02.png
└── album-y
├── 01.jpg
├── 02.png
└── 03.gif
rename
実用的な事項物事が簡単になったら使用してください。
主な問題は、各ファイルがどれだけ得られるべきかを把握することです。入れ子になったfor
ループを使用して繰り返し、サブフォルダを作成し、event-x
各内部ループについて直接数値を追跡する必要がありますかalbum-x
、それとも私が見逃した賢い解決策はありますか?
答え1
for dir in */*; do # loop over the directories
( # run in a subshell ...
cd "$dir" # ... so we don't have to cd back
files=(*) # store the filenames in a zero-indexed array
for index in "${!files[@]}"; do
file=${files[$index]}
ext=${file##*.}
newname=$(printf "%02d.%s" $((index+1)) "$ext")
mv "$file" "$newname"
done
)
done
拡張子のないファイルがあるとしましょう。この場合、前の数字を除いて名前は同じです(例:my_file
=> 05.my_file
)。
ディレクトリを含む非表示にされていないすべてのディレクトリエントリの名前が変更されます。
答え2
ここには2つの質問があります。
- ディレクトリに再帰します。
- 各個々のディレクトリで番号付けシステムを再起動します。
これにより、どちらの場合もスムーズに処理されますが、他の拡張も含めることにした場合は、IMAGE_TYPES変数を変更する必要があります。
#!/bin/bash
shopt -s extglob
shopt -s nocaseglob
IMAGE_TYPES='jpg|png|gif'
IFS=$'\n' dirlist=(`find "$PWD" -type d`)
for dir in "${dirlist[@]}"; do
cd "$dir"
ls *.+($IMAGE_TYPES) > /dev/null 2>&1 || continue
counter=0
for file in *.+($IMAGE_TYPES); do
printf -v newname "%.3d.%s" $((counter += 1)) "${file##*.}"
mv --verbose "$file" "$newname"
done
done
答え3
私は同じツリーを作成し、モバイルビルドを実行しました。これが私が思いついたものです:
n=0 IFS=.; set -f ./[e]vent*/*/*
for f do [ -n "${f##./\[*}" ] || break
[ "$d" = "${f%/*}" ] || i=0 d=${f%/*}
mv=': mv "${'$((n=$n+1))'}" "${'$n'%%/*}/'
printf "$mv%.2d%.0s.%s\"\n" $((i=$i+1)) ${f##*/}
done | sh -sx -- "$@"
最後のパイプがない場合は、|
次を印刷します。
mv "${1}" "${1%/*}/01.jpg"
mv "${2}" "${2%/*}/02.png"
mv "${3}" "${3%/*}/01.jpg"
mv "${4}" "${4%/*}/02.png"
mv "${5}" "${5%/*}/03.gif"
mv "${6}" "${6%/*}/01.jpg"
mv "${7}" "${7%/*}/02.png"
mv "${8}" "${8%/*}/01.jpg"
mv "${9}" "${9%/*}/02.png"
mv "${10}" "${10%/*}/03.gif"
わかりましたが、あまりそうではありませんが、ここで重要なのは、奇妙なファイル名や他のものについて心配する必要はないということです。この出力の目的のターゲットは、for
ループを共有して出力を生成したシェルです。位置の配列。私のコマンドには次のコマンドがあります。次のデバッグ出力を提供するように構成されています。
+ : mv ./event-a/album-a/a.jpg ./event-a/album-a/01.jpg
+ : mv ./event-a/album-a/x.png ./event-a/album-a/02.png
+ : mv ./event-a/album-b/a.jpg ./event-a/album-b/01.jpg
+ : mv ./event-a/album-b/x.png ./event-a/album-b/02.png
+ : mv ./event-a/album-b/y.gif ./event-a/album-b/03.gif
+ : mv ./event-b/album-x/a.jpg ./event-b/album-x/01.jpg
+ : mv ./event-b/album-x/x.png ./event-b/album-x/02.png
+ : mv ./event-b/album-y/a.jpg ./event-b/album-y/01.jpg
+ : mv ./event-b/album-y/x.png ./event-b/album-y/02.png
+ : mv ./event-b/album-y/y.gif ./event-b/album-y/03.gif
:
これがフォーマット文字列の最初の文字の場合の外観ですprintf
。それを削除してコマンドを実行すると、次のようになります。
ls ./event*/*/
./event-a/album-a/:
01.jpg 02.png
./event-a/album-b/:
01.jpg 02.png 03.gif
./event-b/album-x/:
01.jpg 02.png
./event-b/album-y/:
01.jpg 02.png 03.gif
これはあなたの要件を満たすようです。結果に勝つことはできないと思います。
答え4
ファイル名がわかっている場合は、次を実行してその番号を取得できます。
ls -1 <your_dir> | grep <file_name> -B 1000 | wc -l