Mengubah nama file batch

151

Saya memiliki direktori yang penuh dengan gambar:

image0001.png
image0002.png
image0003.png
...

Dan saya ingin liner satu untuk mengubah nama mereka menjadi (katakanlah).

0001.png
0002.png
0003.png
...

Bagaimana saya melakukan ini?

Manusia internet
sumber
8
Ini adalah salah satu FAQ baris perintah Unix teratas, dan saya belum dapat menemukannya di situs ini, jadi haruskah kita membuat Wiki Komunitas ini?
Gilles
5
Saya tidak mengerti mengapa. Ini adalah pertanyaan khusus dengan jawaban yang dapat diverifikasi.
Manusia internet
3
Jika Anda menjalankan X, itu tidak akan jauh lebih mudah daripada thunar -B *.pngalat gui massal-ganti thunar.
dotjoe
@ Dojjoe Terima kasih, Thunar memang menarik.
Volker Siegel

Jawaban:

106

Jika Anda menggunakan Bash atau shell yang kompatibel dengan POSIX:

for f in *.png; do
    mv -- "$f" "${f#image}"
done
W_Whalley
sumber
2
Ini adalah salah satu metode substitusi parameter yang ditampilkan dalam Mendel Coopers Advanced Bash-scripting guide tldp.org/LDP/abs/html
W_Whalley
2
@ W_Whalley Saya sangat merekomendasikan untuk menghindari panduan itu, demi Panduan Wooledge Bash .
Wildcard
@ Kartu Memori: apa alasan Anda merekomendasikan untuk menghindari panduan ABS?
Christian Severin
@ChristianSeverin mempromosikan praktik buruk dan kode langsung rusak. Periksa tautan di halaman profil saya.
Wildcard
Jika Anda tidak tahu bagaimana mengadaptasi contoh ini untuk pola file yang berbeda, Anda mungkin ingin melihat Bagian Ekspansi Parameter dari panduan yang disebutkan di atas.
lex82
108

Pada Debian dan turunannya, renamekarya Perl mirip sedseperti ini:

  rename -v 's/image//' *.png

Ada juga renamedari util-linuxyang bekerja seperti ini, sebagai gantinya:

  rename image '' *.png
Manusia internet
sumber
6
Anda benar-benar harus menjelaskan bahwa ini adalah program perl yang mungkin harus diinstal dan dibutuhkan ekspresi reguler sebagai argumen.
Ah, saya tidak menyadarinya. Saya akan memberikan penghargaan untuk jawaban kanonik, ketika saya mengidentifikasinya :)
Internet man
5
renameProgram ini berasal dari distribusi contoh Perl. Debian dan Ubuntu mengirimkannya sebagai /usr/bin/rename. Varian Unix lain mungkin tidak menyediakannya, atau mungkin memberikan yang sama sekali berbeda /usr/bin/rename.
Gilles
1
Beberapa versi renametake a from to replacement pattern:rename [options] <expression> <replacement> <file>...
melds
1
Jika Anda menggunakan sistem berbasis Debian maka sudo apt-get install rename, maka Anda dapat menggunakan perintah rename. Itu sed untuk nama file.
ctrl-alt-delor
41

zmv

Shell zsh memiliki perintah mengubah nama bets kuat yang disebut zmv.

Pertama, Anda perlu mengaktifkan zmvperintah sebagai berikut (ini bisa masuk ke Anda ~/.zshrc).

autoload zmv

Sintaks dasarnya adalah zmv PATTERN REPLACEMENT. Polanya adalah ekspresi shell glob. Bagian dari pola dapat dikelilingi oleh tanda kurung. Teks pengganti dapat berisi $1,, $2dll. Untuk merujuk ke grup kurung ke-N dalam pola. Sebagai contoh:

zmv 'image(*.png)' '$1'

Anda juga dapat meminta zsh untuk secara otomatis menentukan $1, $2, dll untuk mencocokkan karakter wildcard dalam pola:

zmv -w 'image*.png' '$1.png'
Gilles
sumber
4
sweeeeeeeeeeeeeeeeeet. Belum alasan lain saya harus belajar zsh.
ixtmixilix
1
@ixtmixilix apa yang harus dipelajari? Mulailah menggunakannya dan mungkin tambahkan prezto ( github.com/sorin-ionescu/prezto ) untuk beberapa keangkeran ekstra.
Gerry
Benar-benar keren, seperti yang ditunjukkan pada pria zmv, ini dapat disederhanakan dengan menambahkan alias mmv = 'noglob zmv -W' ke: mmv * .c.orig orig / *. C
Bretsko
Mengaktifkan zmvprezto membutuhkan tanda komentar pada baris di ~ / .zpreztorc Anda setelah # Set the Zsh functions to load (man zshcontrib).pemberianzstyle ':prezto:load' zfunction 'zargs' 'zmv'
33

Saya biasanya menggunakan utilitas mmv ( halaman manual ) yang bagus dan sederhana untuk penggunaan ini:

$ mmv "image*.png" "#1.png"

akan melakukan tugas Anda.

The #1dalam pola target akan diganti dengan apa pun sesuai dengan wildcard dalam pola sumber. Ini juga berfungsi untuk beberapa wildcard dan dapat digunakan misalnya untuk mengubah urutan bagian nama file. Anda juga dapat dengan mudah melakukan hal-hal yang lebih rumit seperti mengubah huruf kecil menjadi huruf besar.

Pastikan untuk melindungi pola dari cangkang dengan mengutip.

Marcel Stimberg
sumber
Terima kasih telah menunjukkan utilitas ini. Saya menemukannya di repositori Debian, Ubuntu dan Cygwin. Saya mengalami masalah dengan halaman manual, tetapi menemukan beberapa halaman web dan pertanyaan Stack Overflow ini yang membantu menjelaskan bagaimana Anda menggunakannya. stackoverflow.com/questions/417916/how-to-do-a-mass-rename
W_Whalley
Terima kasih, saya menambahkan beberapa informasi pada jawaban untuk membuatnya lebih jelas.
Marcel Stimberg
3
Tidak bisa cukup mengunggahnya! Ini sangat sederhana dan ramah. Tersedia untuk OS X di homebrew.
Greg Dubicki
9

POSIX sh untuk loop

Menggunakan sed untuk mengganti nama

for i in image*jpg
do 
  mv -v "$i" "$(echo "$i" | sed -e 's/^\.\/image//' - )"
done
X Tian
sumber
6

Saya suka Perl:

perl -nlE '$old=$_; s/image//; qx(mv $old $_)'

Anda juga dapat menggunakan pola yang sama untuk tugas-tugas lain seperti menyalin file ke direktori lain:

perl -nlE '$old=$_; s(image)(/path/to/new/dir/); qx(mv $old $_)'
gvkv
sumber
2
Atau (lebih aman!):rename($old,$_)
reinierpost
5

qmv

Perintah qmvdari renameutilsmembuka editor yang memperlihatkan daftar nama file dengan dua kolom, dipisahkan oleh tab. Setiap baris menunjukkan salah satu nama file, sama di kedua kolom. Kolom kanan mewakili nama-nama baru file.
Untuk melakukan perubahan, edit nama di sisi kanan. Dalam contoh ini, :%s/...atau mode blok visual sangat membantu.

Nama file di editor Anda

$ qmv *.png

Dalam editor:

image0001.png           image0001.png
image0002.png           image0002.png
image0003.png           image0003.png         
~                                             
~                                             
~                                             
~                                             
"/tmp/user/1000/qmvxWyVMs" 3L, 93C

Edit nama di kolom kanan:
(Menghapus imageawalan dari semua baris menggunakan mode blok visual)

image0001.png           0001.png
image0002.png           0002.png
image0003.png           0003.png         
~                                             
~                                             
~                                             
~                                             
:wq

Log penamaan ulang:

image0001.png -> 0001.png
image0002.png -> 0002.png
image0003.png -> 0003.png

(misalnya Ubuntu: apt-get install renameutils)

Volker Siegel
sumber
3

rekursif

mudah berulang memilih file gambar * png, dan mengasumsikan tidak perlu berurusan dengan baris baru dalam nama file

find . -name "image*.png" | while read f; do mv -v "$f" "$(echo "$f" | sed -e 's/^\.\/image//' - )"; done

Aman, dapat menangani spasi, garis baru, garis miring terbalik, dan apa pun yang lain :

find . -name "image*.png" | while IFS= read -r f; do 
   mv -v "$f" "$(echo "$f" | sed -e 's/^\.\/image//' - )"; 
done
X Tian
sumber
1

POSIX sh menggunakan loop sementara

Membaca nama dari findperintah.

find . -maxdepth 1 -type f -name 'image*png' | while IFS= read -r f; do
  mv -v "$f" "$(echo "$f" | sed -e 's/^\.\/image//' - )"
done

Membaca nama dari file

while IFS= read -r f; do mv -v "$f" "$(echo "$f"|sed -e 's/^\.\/image//' - )"; done < flist
X Tian
sumber
1

Menggunakan ekspansi brace shell :

for N in {0001..1000}; do mv "{image,}$N.png"; done
αғsнιη
sumber
1

Untuk Windows dan linux , skrip Perl ini akan berfungsi; pada kasus ini:

$ rnm -l 's/^image//' '*.png'

Script dapat dijalankan secara rekursif di bawah direktori dan bahkan menambahkan hitungan ke semuanya:

$ rnm -r 's/^/$counter./' '/\.png$/'

Karakter UTF-8 juga diperlakukan dengan benar, baik di Windows maupun linux.

circulosmeos
sumber
0

Anda dapat menggunakan alat ini: rnm ( halaman web )

Untuk kasus Anda, perintahnya adalah:

rnm -rs '/^image//' *.png

Anda dapat menemukan lebih banyak contoh / dokumen di sini .

Jahid
sumber
0

Coba brename ( https://github.com/shenwei356/brename ), alat baris perintah lintas platform praktis untuk menamai ulang file / direktori dengan aman melalui ekspresi reguler (mendukung Windows, Linux dan OS X).

@patrickDurusau berkata:

Linux memiliki berbagai opsi penggantian nama file batch, tetapi saya tidak melihat adanya kekurangan dalam brename yang muncul pada saya.

Fitur:

  • Lintas-platform . Mendukung Windows, Mac OS X dan Linux.
  • Aman . Dengan memeriksa potensi konflik dan kesalahan .
  • Pemfilteran file . Mendukung termasuk dan tidak termasuk file melalui ekspresi reguler. Tidak perlu menjalankan perintah seperti find ./ -name "*.html" -exec CMD.
  • Mengganti nama pengiriman dengan nilai yang sesuai melalui file nilai kunci .
  • Mengganti nama melalui ascending integer .
  • Mengubah nama file dan direktori secara rekursif .
  • Mendukung dry run .
  • Output berwarna-warni .

Perintah:

$ brename -f .png -p image
[INFO] checking: [ ok ] 'image0001.png' -> '0001.png'
[INFO] checking: [ ok ] 'image0002.png' -> '0002.png'
[INFO] checking: [ ok ] 'image0003.png' -> '0003.png'
[INFO] 3 path(s) to be renamed
[INFO] renamed: 'image0001.png' -> '0001.png'
[INFO] renamed: 'image0002.png' -> '0002.png'
[INFO] renamed: 'image0003.png' -> '0003.png'
[INFO] 3 path(s) renamed
Wei Shen
sumber
-5

ls * png | saat membaca -rf; do f2 = "` echo $ f | sed -e's / image // '`"; mv $ f $ f2; Selesai

Ivan P
sumber
Sesuatu yang tidak beres: "mv: operan file tujuan hilang setelah 'image0001.png'"
Internet man
3
Ada banyak masalah dengan kode Anda. Mengurai output lshanya memanggil masalah. readseharusnya read -r. semua penggantian variabel harus dalam tanda kutip ganda.
Gilles
Anda dapat menulis ini dengan lebih efektif for f in *png; do f2="$(echo "$f" | sed -e 's/image//')"; mv "$f" "$f2"; done. Parsing lstidak perlu atau bukan ide yang baik .
kojiro