Bagaimana cara mengganti nama banyak file secara berurutan dari baris perintah?

15

Cara mengganti nama file seperti di bawah ini

AS1100801000002.RAW7AGS 
AS1100801001008.RAW7AH4
AS1100801002001.RAW7AH9
AS1100801003002.RAW7AHE
AS1100801004009.RAW7AHT
AS1100801005002.RAW7AHY
AS1100801010002.RAW7AJ3

ke nama baru

AS1.txt
AS2.txt
AS3.txt
AS4.txt
AS5.txt
AS6.txt
AS7.txt
kamaruz85
sumber

Jawaban:

22

The renamealat yang kapal dengan Ubuntu cukup panas di hal semacam ini. Anda dapat menanamkan sedikit ekspresi Perl seperti:

rename -n 's/.+/our $i; sprintf("AS%d.txt", 1+$i++)/e' *

Itu hanya akan menunjukkan kepada Anda apa yang akan dilakukan. Lepaskan -nuntuk menjadikannya latihan tembakan langsung.

Ini pada dasarnya bekerja dengan mendefinisikan variabel secara kasar dan menambahkannya setiap file yang kita tekan. Jika Anda akan memiliki lebih dari 10 file, saya sarankan menggunakan beberapa zero-padding di sprintf. Berikut ini bagus untuk 999:

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

... Tapi itu cukup mudah untuk diperluas.

Oli
sumber
4

Saya tidak tahu satu perintah atau utilitas yang akan melakukan ini, tetapi cukup mudah untuk dilakukan dengan loop sederhana:

N=1
for X in AS*RAW*; do
  mv $X AS$N.txt
  N=$(($N+1))
done
Paul
sumber
3

Untuk meningkatkan jawaban @ Oli , versirename alat 1.600 oleh Aristoteles Pagaltzis sebenarnya memiliki penghitung bawaan$N ,.

Jadi yang Anda butuhkan adalah,

rename 's/AS.*/AS$N/' *

Untuk memasang,

  1. brew install renameatau Unduh skripnya
  2. Simpan ke direktori di jalur sistem Anda (biasanya /usr/local/bin/brewatau /usr/bin)
Atav32
sumber
3
Ini tampaknya menjadi alat yang berbeda dengan nama yang sama. Default Ubuntu renameadalah nama depan. Ini mungkin lebih baik tetapi Anda mungkin ingin menambahkan instruksi pemasangan untuk membuat jawaban ini lebih berharga.
Oli
1
@Oli panggilan yang bagus! diperbarui.
Atav32
2

renamememungkinkan Anda menetapkan langsung ke $_, yang ideal untuk masalah ini.

Meskipun argumen kode yang kita berikan ke renameutilitas Perl sering melakukan pencocokan dan penggantian (dengan s/), dan benar-benar dapat diterima untuk memecahkan masalah ini dengan cara itu , benar-benar tidak perlu untuk itu dalam kasus seperti ini di mana Anda tidak benar-benar memeriksa atau menggunakan kembali teks nama file lama. renamememungkinkan Anda menulis hampir semua kode Perl, dan itu tidak perlu tertanam di dalamnya s/ /e. Saya sarankan menggunakan perintah seperti ini:

rename -n 'our $i; $_ = sprintf "AS%02d.txt", ++$i' *

Atau, jika Anda ingin menghilangkan beberapa karakter:

rename -n '$_ = sprintf "AS%02d.txt", ++our$i' *

(Itu bisa dibuat lebih pendek, tetapi bukan tanpa mengorbankan kejelasan.)

Kedua perintah itu melakukan hal yang sama. Masing-masing menunjukkan operasi penggantian nama apa yang akan dilakukan. Setelah Anda mencobanya dan Anda puas dengan hasilnya, jalankan kembali tanpa -nopsi. Seperti ditulis, ini akan menghasilkan nama file AS01.txt, AS02.txt, ..., AS10.txt, AS11.txt, dan sebagainya. Anda dapat memodifikasinya sesuai kebutuhan, kemudian hanya menghapus -nketika Anda suka apa yang Anda lihat.

Jika Anda ingin menambah lebih dari 2, gantilah 2dengan yang lebih besar. Misalnya, jika karena alasan tertentu Anda menginginkan nama file seperti AS00000000000001.txt, Anda akan menggantinya %02ddengan %014d. Jika Anda tidak ingin menggunakan padding sama sekali - walaupun itu akan membuat file Anda muncul dalam urutan non-numerik ketika Anda mendaftar nanti! - maka Anda dapat menggantinya %02ddengan adil %d.

Bagaimana cara kerjanya? Shell Anda mengembang * menjadi daftar file bahkan sebelum menjalankan renameperintah. Daftar ini diurutkan secara leksikografis (yaitu, menurut abjad) sesuai dengan pengaturan lokal Anda saat ini. renamemenerima nama file sebagai argumen baris perintah dan memprosesnya dalam urutan yang terdaftar. Ekspresi ++$idievaluasi menjadi lebih besar dari nilai saat ini dari variabel $i, dan juga menetapkan variabel $ike nilai yang baru bertambah. Nilai ini diteruskan ke sprintf, yang memformatnya dan menempatkannya di dalam teks lain. Teks ini ditugaskan langsung ke variabel khusus $_, yang memegang nama file. Karena renameproses file dalam urutan mereka dilewatkan sebagai argumen, mereka diberi nomor sesuai.


Anda mungkin memperhatikan kesamaan dengan jawaban Oli !

Keduanya mendeklarasikan dan menambahkan variabel penghitung, dan keduanya sprintfpada dasarnya menggunakan cara yang sama untuk menanamkan nilai penghitung itu, diisi di sebelah kiri dengan nol, dalam teks lain dari nama file baru. (Informasi dalam salah satu jawaban tentang cara membuat pad dengan nol - dan mengubah lebar padding - bahkan berlaku sama untuk keduanya.) Alasan mereka sangat mirip adalah bahwa metode dalam jawaban yang lebih lama benar-benar melakukan hanya 1 ini , tetapi dengan langkah-langkah tambahan yang berguna untuk banyak masalah tetapi sebenarnya tidak perlu untuk yang satu ini.

Sebagai perbandingan, inilah yang tampak seperti perintah kedua dalam jawaban itu jika dimodifikasi untuk menggunakan gaya yang saya gunakan di sini (dan untuk menambah lebar 2, seperti yang telah saya lakukan di sini, bukannya 3):

rename -n 's/.+/our $i; sprintf "AS%02d.txt", ++$i/e' *

Bagian antara s/.+/dan /edalam perintah itu sekarang sama dengan ekspresi yang saya tetapkan $_(yaitu, kode di sisi kanan =operator) dalam perintah pertama dalam jawaban ini.

  • The s/ Operator upaya untuk teks pertandingan (nama file yang shell Anda diperluas dari *dan lulus sebagai argumen baris perintah ketika berlari rename) dengan ekspresi reguler , dan substitusi penampilannya. /sedang digunakan sebagai pembatas untuk memisahkan bagian sekspresi yang berbeda. Bagian pertama .+,, adalah ekspresi reguler; cocok dengan 1 karakter ( .) , dan melakukannya satu atau beberapa kali ( +) . Karena nama file tidak pernah kosong - mereka selalu memiliki setidaknya satu karakter - ini adalah salah satu cara untuk mencocokkan 1 nama file.
  • Kemudian menghasilkan teks dari setiap pertandingan - yaitu, dari setiap nama file keseluruhan - terdiri dari our $i; sprintf "AS%02d.txt", ++$i. Ini menghasilkan nama file baru. Biasanya, seseorang menggunakan s/untuk menghasilkan teks yang (a) menggantikan teks yang hanya cocok dengan sebagian dari nama file, atau (b) berdasarkan teks yang cocok dalam beberapa cara (misalnya, mungkin menggunakan variabel khusus seperti $&yang diperluas ke pertandingan). Namun, dalam kasus ini, teks yang cocok tidak digunakan sama sekali.
  • Biasanya teks yang diganti our $i; sprintf "AS%02d.txt", ++$iakan digunakan sebagai nama file, bukan dijalankan sebagai kode. Tetapi /ebendera pada akhirnya menyebabkan teks diperlakukan sebagai kode sumber Perl dan dievaluasi, dan menggunakan nilai yang dihasilkan dengan melakukan hal itu (dalam hal ini, nilai pengembalian sprintffungsi bawaan Perl ) sebagai nama file baru.

Meskipun saya pikir metode yang saya sudah ditampilkan di sini adalah jelas dan sederhana pendekatan untuk masalah ini daripada metode apapun yang menggunakan s/dengan /e, baik itu untuk menyadari teknik yang, karena sangat cocok untuk sejumlah mengubah nama masalah file lain di mana semua atau bagian dari nama file asli diperiksa dan / atau dipertahankan. Saya merekomendasikan posting blog ini oleh Oli (yang juga menulis jawaban itu ), yang mencakup beberapa contohnya.

1 Secara teknis, ada adalah perbedaan dalam perilaku $_ =perintah dan s/ /eperintah. Dalam ekspresi reguler .+, tidak sepenuhnya benar yang .cocok dengan karakter apa pun , karena tidak cocok dengan baris baru . Anda mungkin sebaiknya tidak menggunakan nama file dengan baris baru di dalamnya, tetapi Anda bisa, dan kadang-kadang sebuah file dinamai demikian secara tidak sengaja. Jika Anda suka, kontraskan keluaran rename -n 'our $i; $_ = sprintf "AS%02d.txt", ++$i' $'foo\nbar'ke yang rename -n 's/.+/our $i; sprintf "AS%02d.txt", ++$i/e' $'foo\nbar'. Untuk membuat .kecocokan dengan baris baru, gunakan sbendera, yang berada di bagian akhir (dengan e). Yaitu, tulis /sedi akhir, bukan /e.

Eliah Kagan
sumber
0

Misalkan file yang Anda ingin rename berada ~/Adir, dan ini adalah satu-satunya file dalam folder ini, kemudian:

n=0
for f in $( ls ~/Adir | sort ) ; do
    n=$(( n+1 ))
    mv -n "$f" "AS${n}.txt"
done

Script ini akan melihat setiap file di ~/Adirdan mengganti nama ke AS1.txt, AS2.txt, ...jika file tidak ada (tidak akan ada overwritting). Itu sebabnya Anda harus memastikan ini adalah satu-satunya file di ~/Adir. The sortperintah hanya dalam kasus Anda ingin file untuk menjaga pesanan awal.

edwin
sumber
0

Meskipun OP memerlukan opsi baris perintah, ia juga tersedia sebagai opsi GUI di Nautilus dan cukup mudah.

Pilih semua file yang diperlukan dan tekan F2. Ada opsi yang disebut Nomor Otomatis. Anda dapat menambahkannya ke teks yang Anda butuhkan.

Sandeep C
sumber