Ganti nama grup file dengan satu perintah


38

Jika saya memiliki sekelompok file dengan ekstensi .htm, bagaimana saya bisa mengubah nama semuanya menjadi .html?

mv *.htm *.html

tidak bekerja.


Hanya demi kelengkapan, ren *.htm *.htmlakan berfungsi di Windows.
Brian Burns

Jawaban:


50

Atau, Anda dapat menggunakan bash murni ... (kecuali untuk mv, yaitu ..)

for file in *.htm; do mv "$file" "${file%.htm}.html"; done

dan hindari hal-hal nama dasar yang tidak menyenangkan ;)

Bash memiliki serangkaian opsi ekspansi variabel yang luas. Yang digunakan di sini, '%', menghapus akhiran pencocokan terkecil dari nilai variabel. Polanya adalah pola gumpal, jadi ${file%.*}akan juga berfungsi. Operator '%%' menghilangkan akhiran pencocokan terbesar, dan dapat dipertukarkan dalam contoh di atas, karena polanya diperbaiki, ${file%%.*}.htmlakan mengubah abhtm menjadi a.html.

Lihat bagian substitusi variabel dari halaman bash untuk trik yang lebih rapi. Ada banyak yang bisa dilakukan dalam bash secara langsung.


1
Perhatikan juga bahwa ekspansi parameter ini tidak terbatas pada bash . Mereka tersedia pada semua shell yang diturunkan dari Bourne ( sh , ksh , bash , zsh , dash , ash , dll.). Ekspansi adalah bagian dari spesifikasi POSIX untuk "Shell Command Language" dan sangat portabel.
Chris Johnsen

11

Seharusnya tidak ada spasi, baris baru atau spasi putih di nama file, tetapi versi freiheit ini menjawabnya. Itu juga menggunakan $()bukannya backticks untuk dibaca bersama dengan manfaat lainnya.

for file in *.htm
do
    mv "$file" "$(basename "$file" .htm).html"
done

Bahkan lebih baik - untuk kasus khusus dengan menambahkan sampai akhir:

for file in *.htm
do
    mv "$file" "${file}l"
done

11

rename(1)adalah utilitas Perl yang melakukan persis apa yang Anda inginkan. Pada kasus ini:

rename 's/\.htm$/.html/' *htm

atau jika Anda menggunakan sub direktori juga

(membutuhkan Bash 4.0 dan pengaturan globstar: shopt -s globstar)

rename 's/\.htm$/.html/' **/*htm


1
mengganti nama lebih mudah, tetapi bukan program unix standar; pertanyaan asli tidak menentukan unix mana. Tampaknya menjadi "nama kecil" di beberapa tempat.
freiheit

2
renamedatang dengan perl, dan pada dasarnya setiap unix datang dengan perl hari ini.
TRS-80

3
ya, tetapi tidak setiap unix menyertakan program tambahan seperti 'rename' ketika mereka menempatkan perl pada sistem. OSX, misalnya, tidak memiliki "ganti nama" di atasnya.
freiheit

1
@ William: Sintaks asterisk ganda hanya tersedia di Bash 4 dan lebih tinggi dan hanya jika diaktifkan dengan shopt -s globstar(dinonaktifkan secara default). Juga, Linux dan Unix memiliki direktori daripada folder.
Dijeda sampai pemberitahuan lebih lanjut.

6
for file in *.htm; do
  mv $file `basename "$file" .htm`.html
done

Cobalah dengan echodi depan mvpertama kali.

Masalah dengan dokumen asli Anda adalah " mv *.htm *.html" *s telah ditangani oleh shell, jadi mvperintahnya hanya melihat daftar semua file .htm dan .html di direktori saat ini. Dengan kata lain, sesuatu seperti " mv foo.htm bar.htm stuff.htm six.htm file.htm". mv hanya tahu cara menangani lebih dari 2 argumen jika yang terakhir adalah direktori.


1
Anda harus mengutip "$ file", untuk menangani spasi.
Richard Hoskins

Deskripsi Anda tentang masalah awal harus ditekankan lebih kuat. Perilaku ekspansi wildcard shell ini mengejutkan dan tidak intuitif untuk seseorang yang datang dari Windows land, dan memahami apa yang dilakukan shell menjelaskan mengapa aplikasi asli shell mvtidak berfungsi.
Greg Hewgill

3

Namun contoh bash murni lainnya menggunakan string replace.

for file in *.htm; do mv $file ${file/htm/html}; done

Extra - ini menggantikan semua kemunculan string

for file in *.htm; do mv $file ${file//htm/html}; done



0

Paket util-linux-ng (di Fedora) memiliki renameperintah yang mirip dengan yang disebutkan oleh TRS-80 . Anda bisa menggunakannya seperti ini:

rename .htm .html *.html
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.