Mengganti nama ratusan file sekaligus untuk pengurutan yang tepat

23

Saya memiliki satu ton file, semua diberi nama hal-hal seperti 1.jpg, 2.jpg, 3.jpg, dan seterusnya sampai 1439.jpg, namun, saya punya masalah dengan salah satu proyek saya dan alfabetis. Ini biasanya akan pergi dalam urutan 1.jpg, 10.jpg, 11.jpgdan sebagainya.

Yang saya butuhkan adalah beberapa cara untuk memberi nama file sehingga mereka berada dalam format seperti 00001.jpgsepanjang jalan 01439.jpg.

Bagaimana saya bisa melakukan ini dengan cepat dan efisien?

Kaz Wolfe
sumber
Apa yang Anda cari adalah "penyortiran alami", mungkin ini membantu: askubuntu.com/questions/41390/…
Fabian Blechschmidt
Jawaban itu bukan jawaban langsung? ls -v unix.stackexchange.com/questions/33909/…
WernerCD
+1 karena saya telah mencoba melakukan ini dengan gagal pyrenamer.
Parto
@FabianBlechschmidt, saya membutuhkan ini dalam program yang bukan untuk nautilus atau sejenisnya. Ini untuk proyek individu.
Kaz Wolfe
Saya pikir Anda berpikir tentang menerapkan penyortiran alami? Tapi saya mengerti, mengganti nama file cukup mudah dan jika berhasil, bagus :)
Fabian Blechschmidt

Jawaban:

35

Ubuntu hadir dengan skrip bernama rename. Hanya sedikit skrip Perl yang menampilkan sejumlah fitur penggantian nama massal yang kuat tetapi yang terbaik (dalam hal ini) adalah kemampuannya untuk menjalankan Perl selama penggantian. Hasilnya adalah solusi yang benar-benar kompak:

rename 's/\d+/sprintf("%05d", $&)/e' *.jpg

Ini mirip dengan printfjawaban-gaya lain di sini tapi itu semua ditangani untuk kita. Kode di atas adalah untuk angka 5 digit (termasuk angka variabel nol di awal).

Ini akan mencari dan mengganti angka-string pertama yang ditemukannya dengan versi nol-empuk dan meninggalkan sisa nama file. Ini berarti Anda tidak perlu terlalu khawatir membawa ekstensi atau awalan.

Catatan: ini tidak sepenuhnya portabel. Banyak distribusi menggunakan rename.uldari util-linuxpaket sebagai renamebiner default mereka . Ini adalah alternatif yang terhambat secara signifikan (lihat man rename.ul) yang tidak akan memahami hal di atas. Jika Anda ingin ini pada platform yang tidak menggunakan nama Perl, temukan cara menginstalnya terlebih dahulu.


Dan inilah test harness:

$ touch {1..19}.jpg

$ ls
10.jpg  12.jpg  14.jpg  16.jpg  18.jpg  1.jpg  3.jpg  5.jpg  7.jpg  9.jpg
11.jpg  13.jpg  15.jpg  17.jpg  19.jpg  2.jpg  4.jpg  6.jpg  8.jpg

$ rename 's/\d+/sprintf("%05d", $&)/e' *.jpg

$ ls
00001.jpg  00005.jpg  00009.jpg  00013.jpg  00017.jpg
00002.jpg  00006.jpg  00010.jpg  00014.jpg  00018.jpg
00003.jpg  00007.jpg  00011.jpg  00015.jpg  00019.jpg
00004.jpg  00008.jpg  00012.jpg  00016.jpg

Dan contoh awalan (kami tidak melakukan hal yang berbeda):

$ touch track_{9..11}.mp3 && ls
track_10.mp3  track_11.mp3  track_9.mp3

$ rename 's/\d+/sprintf("%02d", $&)/e' *.mp3 && ls
track_09.mp3  track_10.mp3  track_11.mp3
Oli
sumber
Jika saya seorang Perl, ini akan menjadi solusi yang sempurna. Sangat rapi.
MGP
2
Itu tidak menggunakan perl, hanya alat yang disediakan yang sudah ditulis dalam perl.
Rob
1
Dalam hal ini memang melibatkan satu perintah Perl tetapi itu bukan mengangkat terlalu berat. sprintfdi Perl berperilaku mirip dengan sprintfdalam bahasa lain.
Oli
21
for f in *.jpg ; do if [[ $f =~ [0-9]+\. ]] ; then  mv $f `printf "%.5d" "${f%.*}"`.jpg  ; fi ; done

Edit

Penjelasan:

  • if [[ $f =~ [0-9]+\. ]] memastikan bahwa hanya file yang namanya angka (diikuti titik) yang diganti namanya.
  • printf "%.5d" NUMBER menambahkan nol terkemuka
  • "${f%.*}" memotong ekstensi (.jpg) dan hanya menyisakan nomor
  • .jpgsetelah backtick kedua menambahkan ekstensi file lagi.

Perhatikan bahwa ini hanya akan berfungsi pada nama file yang angka. Nol terkemuka yang mengarah ke kiri ke file yang tidak bernomor akan membutuhkan format yang berbeda.

Jika Anda ingin bereksperimen coba perintah ini:

for f in *.jpg ; do if [[ $f =~ [0-9]+\. ]] ; then echo mv $f `printf "%.5d" "${f%.*}"`.jpg  ; fi ; done

Edit 2

Membuat perintah lebih aman dengan memastikan bahwa hanya nama file yang angka sedang diganti namanya. Perhatikan bahwa file yang sudah ada sebelumnya yang bernama 00001.jpg akan ditimpa.

sмurf
sumber
Skrip satu liner ini berfungsi 'di luar kotak' di Ubuntu dan distro Linux lainnya! 😃 Tidak perlu menginstal alat tambahan apa pun menggunakan perl, python, dll.
HEXcube
6

Di bawah skrip python.

Skrip menambahkan angka nol di depan hingga jumlah digit yang ditentukan. Jika nama lebih besar dari itu, file (nama) tidak tersentuh.

Menggabungkan berbagai ekstensi dalam satu tindakan mengubah nama mungkin menambah kenyamanan. Untuk menambahkan ekstensi, cukup tambahkan mereka ke tuple, misalnya extensions = (".jpg", ".jpeg", ".tiff").

Salin teks ke dalam file kosong, simpan sebagai rename.py, masukkan jalur yang benar ke direktori file ( sourcedir), jumlah digit yang Anda ingin memiliki nama baru ( number_ofdigits) dan ekstensi file untuk mengubah nama ( extensions)

Jalankan dengan perintah:

python3 /path/to/script/rename.py

Naskah:

#!/usr/bin/python3

import shutil
import os

sourcedir = "/path/to/files"; number_ofdigits = 5; extensions = (".jpg", ".jpeg")

files = os.listdir(sourcedir)
for item in files:
    if item.endswith(extensions):
        name = item.split("."); zeros = number_ofdigits-len(name[0])
        newname = str(zeros*"0")+name[0]+"."+name[1]
        shutil.move(sourcedir+"/"+item, sourcedir+"/"+newname)

edit:

Di bawah versi yang sedikit lebih baik. Secara otomatis menentukan nama terpanjang dalam direktori, dan menambahkan nol di depan hingga panjang nama terpanjang.

contoh:

1.jpg
12.jpg
123.jpg

menjadi:

001.jpg
012.jpg
123.jpg

Tidak perlu mengatur jumlah digit.

#!/usr/bin/python3

import shutil
import os

sourcedir = "/path/to/files"; extensions = (".jpg", ".jpeg")
files = [(f, f[f.rfind("."):], f[:f.rfind(".")]) for f in os.listdir(sourcedir)if f.endswith(extensions)]
maxlen = len(max([f[2] for f in files], key = len))

for item in files:
    zeros = maxlen-len(item[2])
    shutil.move(sourcedir+"/"+item[0], sourcedir+"/"+str(zeros*"0")+item[0])
Yakub Vlijm
sumber
2

Ada utilitas rename yang diterapkan di Perl yang membuatnya sangat mudah:

rename 's/\d+/sprintf("%05d",$&)/e' *.jpg

Argumen pertama adalah ekspresi Perl yang dievaluasi untuk setiap nama file.

Mats Kindahl
sumber
0

Ada GUI yang akan melakukan ini disebut pyRenamer yang dapat ditemukan di repositori. Instal, mulai, pilih direktori Anda dan cukup tetapkan 'Pola nama file yang diubah namanya' menjadi '{num5}' pada tab 'Pola' dan klik tombol 'Ubah Nama'. Anda juga dapat melihat pratinjau apa yang akan terjadi sebelum penggantian nama.

pengguna287888
sumber
Sementara jawaban Anda TIDAK berfungsi, harap perhatikan bahwa ini adalah shell-scriptingbagian, artinya saya mencari jawaban baris perintah. Juga, dapatkah Anda memberikan detail lebih lanjut tentang program ini? Misalnya, format pola apa itu {num5}?
Kaz Wolfe
-4
for file in `(find * -maxdepth 1 -type f -name "*.jpg")`     
do    
  mv $file "000"$file    
done

Ini kasar, karena tidak melakukan penggantian nama secara cerdas, perlu memikirkan trik untuk itu. Tapi itu akan membantu Anda menyortir barang.

Pembaruan: Yah, Anda punya jawaban yang lebih lengkap.

Swarnendu Biswas
sumber
2
itu mengubah nama 1439.jpg sebagai 0001439.jpg.
Avinash Raj
Ya, saya tahu, hanya menambahkan nol ekstra yang seharusnya masih bisa digunakan.
Swarnendu Biswas