web-dev-qa-db-ja.com

ファイルの名前を連続番号に一括変更する

シェルで大量のファイルの名前を一括で変更しようとしています。インターネット上にたくさんの資料がありますが、特定のケースの解決策が見つからないようです。

「タイムスタンプID」(と思われるもの)を持つファイルがたくさんあります。

abc_128390.png
abc_138493.png
abc_159084.png
...

カウンターと交換したいこと:

abc_001.png
abc_002.png
abc_003.png
...

私の(たくさんの)素朴なアプローチは次のようなものです:

mv abc_*.png abc_{001..123}.png

また、for- loopで機能させる方法を理解できませんでした。

FWIW、残念ながらrenameはこの特定のシステムでは利用できません。

何かアドバイスをいただければ幸いです!

4
NicApicella

もっと賢い方法でカウンターをインクリメントするソリューションを考えることはできませんが、これはうまくいくはずです:

i=0
for fi in abc_??????.png; do
    mv "$fi" abc_$i.png
    i=$((i+1))
done

abc_*.pngは最初のmvが実行される前に展開されるため安全に使用できるはずですが、6文字のタイムスタンプを持つファイルのみが必要なため、終わり。

6
Ulrich Schwarz

Perlパッケージの一部としてrenameユーティリティを使用すると、次のようになります。

rename -n 'our $i; s/_.*/sprintf("_%03d.png", $i++)/e' *.png

注:-nは予行演習用です。ファイルの名前を変更するには、それを削除してください。

4
αғsнιη

zshの場合:

typeset -A count
incr='++count[$1/$2]'
(zmv -n '([^0-9]##)<->(*)(#qn)' '$1${(l:3::0:)$((incr))}$2')

満足したら-nを削除します。

例:

$ ls
a1b.png  abc_128390.png  abc_159084.png  x12y.png
a2b.png  abc_138493.png  a.png           x2y.png
$ typeset -A count
$ incr='++count[$1/$2]'
$ (zmv -n '([^0-9]##)<->(*)(#qn)' '$1${(l:3::0:)$((incr))}$2')
mv -- a1b.png a001b.png
mv -- a2b.png a002b.png
mv -- abc_128390.png abc_001.png
mv -- abc_138493.png abc_002.png
mv -- abc_159084.png abc_003.png
mv -- x2y.png x001y.png
mv -- x12y.png x002y.png
3

既存のファイルを上書きしないでください:

i=1
for fi in abc_??????.png; do
    a="abc_$(printf '%04d' "$i").png"
    if [[ -e $a ]]; then
        echo "file $a exist, not moving $fi"
    else
        mv "$fi" "$a"
    fi
    i=$((i+1))
done
1
Isaac

たとえば、ファイル名を次のように変更したい場合は、cutを使用してファイル名の一部を切り取ることができます。

"1 first.jpg"
"2 second.jpg"
...

"10 first.jpg"
"20 second.jpg"
...

あなたは使うことができます

for i in *jpg; do
  mv -iv "$i" "$(echo "$i"|cut -d\  -f1)0 $(echo "$i"|cut -d\  -f2-99)";
done
1
rubo77