ディレクトリ内のファイルの名前を連番に変更したい。ファイルの作成日に基づく。
例sadf.jpg
to 0001.jpg
、wrjr3.jpg
to 0002.jpg
などの場合、ファイルの合計量に応じて先行ゼロの数(不要な場合は追加のゼロは不要)。
ディレクトリ内のファイルの名前を連番に変更したい。ファイルの作成日に基づく。
例sadf.jpg
to 0001.jpg
、wrjr3.jpg
to 0002.jpg
などの場合、ファイルの合計量に応じて先行ゼロの数(不要な場合は追加のゼロは不要)。
回答:
ループ、、let
およびprintf
パディングに使用してみてください:
a=1
for i in *.jpg; do
new=$(printf "%04d.jpg" "$a") #04 pad to length of 4
mv -i -- "$i" "$new"
let a=a+1
done
-i
フラグを使用すると、既存のファイルが自動的に上書きされるのを防ぎます。
printf -v new "%04d.jpg" ${a}
値を変数に入れることもできます。そして((a++))
、変数をインクリメントするように働きます。また、OPが指定したものである作成日順にパディングを最小化することはありません。ただし、Linux / Unixは作成日を保存しないことに注意してください。
mv -- "$i" "$new"
ダッシュで始まるソースファイル名を正しく処理するために使用することもおそらく望ましいでしょう。そのままでは、mv
このようなファイル名をフラグのコレクションとして解析しようとします。
-i
は答えに含まれるべきだと思いますし、それに応じてメモを書き直すべきです。より安全になります。:(
一行の美しさ:
ls -v | cat -n | while read n f; do mv -n "$f" "$n.ext"; done
あなたは変更することができ.ext
て.png
、.jpg
など、
ls | cat -n | while read n f; do mv "$f" `printf "%04d.extension" $n`; done
します:ゼロ詰めの数値を使用するには
-n
誤ってファイルを上書きしないように、mvコマンドに追加することをお勧めします。これを難しい方法で発見しました!
ls -1prt | grep -v "/$" | cat -n | while read n f; do mv -n "${f}" "$(printf "%04d" $n).${f#*.}"; done
結果:(1)は、修正のために、後で索引を持つ以降のファイルを並べ替えます。(2)ディレクトリを無視します-再帰的ではありません。(3)インデックスを埋め込む。(4)元の拡張子を維持します。
私はそのシンプルさのためにガウテのソリューションが好きですが、重要な欠点があります。何千ものファイルで実行すると、「引数リストが長すぎます」というメッセージ(これについてはさらに詳しく)が表示される可能性があります。次に、スクリプトが非常に遅くなる可能性があります。私の場合、約36.000のファイルで実行すると、スクリプトは約6000移動しました。1秒あたり1つのアイテム!なぜそうなるのかはよくわかりませんが、同僚からのルールは「find
あなたの友達です」でした。
find -name '*.jpg' | # find jpegs
gawk 'BEGIN{ a=1 }{ printf "mv %s %04d.jpg\n", $0, a++ }' | # build mv command
bash # run that command
アイテムをカウントしてコマンドをビルドするために、gawkが使用されました。ただし、主な違いに注意してください。デフォルトでfind
は、現在のディレクトリとそのサブディレクトリ内のファイルを検索するため、必要に応じて、現在のディレクトリのみを検索するように制限しman find
てください(方法の確認に使用)。
NR
短いコマンドで行番号を使用するように変更しました。gawk '{ printf "mv %s %04d.jpg\n", $0, NR }'
$(rm -rf /).jpg
。
for
ループは、厳密に言えば、ファイルごとに1秒を取っていません。ファイルシステムから36,000のファイル名をフェッチしてから、それらを適度にすばやくループするのには長い時間がかかります。多くのファイルシステムでは、実行する正確なコマンドに関係なく、大きなディレクトリに関する問題があります。しかし、通常、一致するファイルのリストfind
をフェッチしてソートする必要があるため、シェルワイルドカードよりも高速になります。
「rename」コマンドを使用
rename -N 0001 -X 's/.*/$N/' *.jpg
または
rename -N 0001 's/.*/$N.jpg/' *.jpg
rename
(Linux Mint 13)には-N
オプションがありません。
rename
命令は大好きですが、知りませんでした-N
!ありがとう!
rename
いる少なくとも3つの異なるツールがあります。@Bostrotによって投稿されたリンクは、さらに別の名前変更ツールであり、@ RomanRhrnNesterovがそれを使用したようです。rename
¶Peder StrayとLarry Wallのすべてのユーザー(perl-rename
arch linuxのパッケージrename
とdebian / ubuntuのパッケージ):$N
自分で定義できます:perl-rename '$N=sprintf("%04d",++$N); s/.*/$N.jpg/' *.jpg
OSXでPeroのソリューションを使用するには、いくつかの変更が必要です。私が使用した:
find . -name '*.jpg' \
| awk 'BEGIN{ a=0 }{ printf "mv \"%s\" %04d.jpg\n", $0, a++ }' \
| bash
注:バックスラッシュは行継続のためにあります
2015年7月20日編集:スペースを含むファイル名をサポートするために\"%s\"
、mv
コマンド
の引数を引用する@klaustopherのフィードバックを組み込みました。
$(rm -rf /).jpg
。
mv
。ieという名前のファイルがある場合some thing.jpg
、スクリプトは失敗します。これは私が使用したものである:find . -name '*.jpg' | awk 'BEGIN{ a=0 }{ printf "mv \"%s"\ wallpaper-%04d.jpg\n", $0, a++ }' | bash
-maxdepth 1
申し訳ありませんが安全である方が良いので、おそらく現在のディレクトリのjpgでのみ作業するために使用します。
ls -1 *.jpg
検索の代わりに使用できます。それ以外の場合は並べ替えられません。または、|sort|
前のawkを追加します
元の拡張を維持し、先行ゼロを追加し、OSXでも機能する非常にシンプルなbash oneライナー:
num=0; for i in *; do mv "$i" "$(printf '%04d' $num).${i#*.}"; ((num++)); done
9.ext
以前11.ext
にソートされませんが、他のツール(などls
)もソートされません。
すべての状況で機能するには、名前にスペースが含まれるファイルに\ "を付けます
find . -name '*.jpg' | gawk 'BEGIN{ a=1 }{ printf "mv \"%s\" %04d.jpg\n", $0, a++ }' | bash
$(rm -rf /)
は引き続き有効です。
rename
がをサポートしていない場合は-N
、次のようなことができます。
ls -1 -c | xargs rename -n 's/.*/our $i; sprintf("%04d.jpg", $i++)/e'
編集特定の数値で開始するには、以下の(やや醜い)コードを使用できます。123を目的の数値に置き換えるだけです。
ls -1 -c | xargs rename -n 's/.*/our $i; if(!$i) { $i=123; } sprintf("%04d.jpg", $i++)/e'
これは、ファイルを作成時刻順にリストし(最初に最新、-r
lsに追加して逆ソートする)、次にこのファイルのリストを送信して名前を変更します。名前の変更では、正規表現のperlコードを使用して、カウンターをフォーマットおよびインクリメントします。
ただし、EXIF情報を含むJPEG画像を処理している場合は、 exiftool
これは、「名前の変更の例」のexiftoolドキュメントからのものです。
exiftool '-FileName<CreateDate' -d %Y%m%d_%H%M%S%%-c.%%e dir
Rename all images in "dir" according to the "CreateDate" date and time, adding a copy number with leading '-' if the file already exists ("%-c"), and
preserving the original file extension (%e). Note the extra '%' necessary to escape the filename codes (%c and %e) in the date format string.
rename
ますか?
OSXで、Homebrewからrenameスクリプトをインストールします。
brew install rename
それからあなたはそれを本当に途方もなく簡単に行うことができます:
rename -e 's/.*/$N.jpg/' *.jpg
または、素敵な接頭辞を追加するには:
rename -e 's/.*/photo-$N.jpg/' *.jpg
Global symbol "$N" requires explicit package name (did you forget to declare "my $N"?) at (user-supplied code).
同様の問題があり、そのためシェルスクリプトを作成しました。誰かに役立つと思うので、良い回答がたくさん投稿されていても、投稿することにしました。自由に改善してください!
@Gnutt次のように入力すると、必要な動作を実現できます。
./numerate.sh -d <path to directory> -o modtime -L 4 -b <startnumber> -r
このオプションを-r
省略した場合、リーマのシミュレーションのみが行われます(テストに役立つはずです)。
オプションLは、ターゲット番号(先行ゼロで埋められます)の長さを示します-p <prefix>
-s <suffix>
。オプションで接頭辞/接尾辞を追加することもできます。
誰かが番号付けされる前にファイルを数値順に並べ替えたい場合は、-o modtime
オプションを削除してください。
これらのファイルが、作成順にリストされたディレクトリにあり、最初が最も古いと仮定します。
a.jpg
b.JPG
c.jpeg
d.tar.gz
e
次にls -1cr
、上記のリストを正確に出力します。次に使用できますrename
:
ls -1cr | xargs rename -n 's/^[^\.]*(\..*)?$/our $i; sprintf("%03d$1", $i++)/e'
出力する
rename(a.jpg, 000.jpg)
rename(b.JPG, 001.JPG)
rename(c.jpeg, 002.jpeg)
rename(d.tar.gz, 003.tar.gz)
Use of uninitialized value $1 in concatenation (.) or string at (eval 4) line 1.
rename(e, 004)
拡張子のないファイルに対しては、「初期化されていない値の使用[…]」という警告が表示されます。無視してかまいません。
コマンドから削除-n
して、rename
実際に名前変更を適用します。
この回答は、2014年4月のルークの回答に触発されました。ファイルの合計量に応じて先行ゼロの数を設定するというGnuttの要件は無視されます。
ls -1tU
、作成時間に変更することで順序を調整できるためです。rename
インストールも必要でしたが、私は持っていませんでした。
ここでも、ほとんど変更せずにPeroのソリューションを使用します。 find
ます。これは、アイテムがディレクトリエントリ内に格納されている順序でディレクトリツリーを走査するためです。これは、(ほとんどの場合)同じマシン上で実行間で一貫しており、削除されていない場合は基本的に「ファイル/ディレクトリの作成順序」になります。
ただし、場合によっては、この例で使用される名前などの論理的な順序を取得する必要があります。
find -name '*.jpg' | sort -n | # find jpegs
gawk 'BEGIN{ a=1 }{ printf "mv %s %04d.jpg\n", $0, a++ }' | # build mv command
bash # run that command
blahblah; rm -r * blahblah.jpg
か?
時間でソートされ、jpg、先行ゼロ、およびベース名に限定されます(必要な場合に備えて)。
ls -t *.jpg | cat -n | \
while read n f; do mv "$f" "$(printf thumb_%04d.jpg $n)"; done
(すべて1行で、なし\
)
ls
、スクリプトで使用するものは何でも賛成投票するのをためらっています。
ls -1tr | rename -vn 's/.*/our $i;if(!$i){$i=1;} sprintf("%04d.jpg", $i++)/e'
rename -vn-オフテストモードでnを削除
{$ i = 1;} -コントロールの開始番号
"%04d.jpg" -カウント04を制御し、出力拡張子.jpgを設定します
rename -v -n 's/../our $i;if(!$i){$i=1;} sprintf("%02d", $i++)/e' *
私にとって、この答えの組み合わせは完璧に機能しました:
ls -v | gawk 'BEGIN{ a=1 }{ printf "mv %s %04d.jpg\n", $0, a++ }' | bash
ls -v
1 10 9を正しい順序で並べるのに役立ちます:1 9 10順序、jpg JPG jpegでのファイル名拡張子の問題を回避gawk 'BEGIN{ a=1 }{ printf "mv %s %04d.jpg\n", $0, a++ }'
4文字と先行ゼロで番号を付け直します。mvを回避することで、誤って同じ番号を使用して、すでにあるものを誤って上書きしようとはしません。bash
実行する@xhienneの発言に注意してください。未知のコンテンツをbashにパイプすることはセキュリティ上のリスクです。しかし、スキャンした写真を使用していたため、これは私には当てはまりませんでした。
lsも使用できます
ls *.JPG| awk 'BEGIN{ a=0 }{ printf "mv %s gopro_%04d.jpg\n", $0, a++ }' | bash
blahblah; rm -r * blahblah.JPG
か?
他のソリューションの大半は、すでに番号として指定されている既存のファイルを上書きします。これは、スクリプトを実行してファイルを追加し、スクリプトを再度実行する場合に特に問題になります。
このスクリプトは、最初に既存の数値ファイルの名前を変更します。
#!/usr/bin/perl
use strict;
use warnings;
use File::Temp qw/tempfile/;
my $dir = $ARGV[0]
or die "Please specify directory as first argument";
opendir(my $dh, $dir) or die "can't opendir $dir: $!";
# First rename any files that are already numeric
while (my @files = grep { /^[0-9]+(\..*)?$/ } readdir($dh))
{
for my $old (@files) {
my $ext = $old =~ /(\.[^.]+)$/ ? $1 : '';
my ($fh, $new) = tempfile(DIR => $dir, SUFFIX => $ext);
close $fh;
rename "$dir/$old", $new;
}
}
rewinddir $dh;
my $i;
while (my $file = readdir($dh))
{
next if $file =~ /\A\.\.?\z/;
my $ext = $file =~ /(\.[^.]+)$/ ? $1 : '';
rename "$dir/$file", sprintf("%s/%04d%s", $dir, ++$i, $ext);
}
このワンライナーは、現在のディレクトリ内のすべてのファイルを一覧表示し、作成タイムスタンプで逆の順序で並べ替え(最も古いファイルが先頭にあることを意味します)、ファイルの数に応じて末尾のゼロで自動的に名前を変更します。ファイル拡張子は保持されます。
私は通常、携帯電話の写真や映画用のフォルダーを1つだけ持っています。このコマンドを適用すると、私の写真とムービーの準備が整い、テレビまたはアーカイブで正しい順序でスライドショーを表示できるようになります。
ファイル名の衝突があると、ファイルが失われることに注意してください。そのため、最初に、何か変な名前に変更してtemp001.jpg
から、最終的なファイル名に実行してください。
DIGITS=$(ls | wc -l | xargs | wc -c | xargs); ls -tcr | cat -n | while read n f; do mv "$f" "$(printf "%0${DIGITS}d" $n).${f##*.}"; done
ls
1回ではなく2回実行することは、このようにしない方がよいように見えますが、これについては詳しく調べていません。
ls
で行われるため、2つ必要です。3.このようなコマンドはワンショットであり、スクリプトに含めることを意図していないため、人々がワンライナーを好む理由があります
ここに私のために働いたものがあります。renameコマンド
を使用して、名前にスペースが含まれているファイルがある場合、mvコマンドがスペースと実際のファイルを混同しないようにしています。
ここで、すべてのjpgファイルについて、ファイル名のスペース、「」を「_」に置き換えました
#!/ bin / bash 名前の変更 'y / / _ /' * jpg#スペースを_で置き換える x = 0とします。 * .jpg;のiの場合 x =(x + 1)とする mv $ i $ x.jpg 終わった
このスクリプトは、Mac OS bashで作成日順にファイルをソートします。私はそれを使ってビデオの名前を一括変更します。拡張子と名前の最初の部分を変更するだけです。
ls -trU *.mp4| awk 'BEGIN{ a=0 }{ printf "mv %s lecture_%03d.mp4\n", $0, a++ }' | bash
blahblah; rm -r * blahblah.mp4
か?
ここで、「rename」コマンドを使用した別のソリューション:
find -name 'access.log.*.gz' | sort -Vr | rename 's/(\d+)/$1+1/ge'
rename 's/(\d+)/sprintf("%04d",$1)+1/ge'
ペロの答えは私をここにもたらしました:)
画像ビューアが時間順に画像を表示しなかったので、時間に関連してファイルの名前を変更したいと思いました。
ls -tr *.jpg | # list jpegs relative to time
gawk 'BEGIN{ a=1 }{ printf "mv %s %04d.jpg\n", $0, a++ }' | # build mv command
bash # run that command
blahblah; rm -r * blahblah.jpg
か?極端な例です。
画像のラベル付けに画像アノテーターを使用している場合。
$ make qt5py3
$ python3 labelImg.py
1つのフォルダにある6000のファイルの番号を変更するには、ACDseeプログラムの「名前の変更」オプションを使用できます。
プレフィックスを定義するには、次の形式を使用します。 ####"*"
次に、開始番号を設定して[名前の変更]を押すと、プログラムはすべての6000ファイルの名前を連番で変更します。