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.

Richard Hoskins
sumber
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.

Falstro
sumber
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
Dijeda sampai pemberitahuan lebih lanjut.
sumber
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

TRS-80
sumber
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.

freiheit
sumber
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
xalupada
sumber
1

Jika Anda menggunakan Zsh, Anda dapat menggunakan 'zmv'

Martin
sumber
1

Alat terbaik adalah mmv .

mmv \*.htm #1.html

Contoh lain penggunaan (dan alat lainnya) dalam " Ringkasan Alat Baris Perintah GNU / Linux ".

bortzmeyer
sumber
1
Contoh penggunaan Anda gagal. Anda harus melarikan diri #.
Cristian Ciupitu
Tidak, ini berfungsi (SAYA SELALU menguji sebelum mengirim di SuperUser). Kebutuhan untuk melarikan diri # tergantung pada shell yang Anda gunakan (saya menggunakan zsh).
bortzmeyer
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
Cristian Ciupitu
sumber