Bagaimana cara mengganti satu char dengan yang lain di semua nama file dari direktori saat ini?


41

Bagaimana Anda mengganti nama semua file / subdirektori di folder saat ini?

Katakanlah, saya punya banyak file dan subdir yang dengan spasi dan saya ingin mengganti semua spasi dengan garis bawah.

File 1
File 2
File 3
Dir 1
Dir 3

harus diubah namanya menjadi

File_1
File_2
File_3
Dir_1
Dir_3

Jawaban:


36

Jika Anda perlu mengganti nama file dalam subdirektori juga, dan Anda findmendukung -execdirpredikatnya, maka Anda dapat melakukannya

find /search/path -depth -name '* *' \
    -execdir bash -c 'mv -- "$1" "${1// /_}"' bash {} \;

Terima kasih kepada @glenn jackman karena menyarankan -depthopsi untuk finddan membuat saya berpikir.

Perhatikan bahwa pada beberapa sistem (termasuk yang GNU / Linux), findmungkin gagal menemukan file yang namanya berisi spasi dan juga urutan byte yang tidak membentuk karakter yang valid (khas dengan file media dengan nama dengan karakter non-ASCII yang dikodekan dalam rangkaian karakter) berbeda dari lokal). Mengatur lokal ke C(seperti pada LC_ALL=C find...) akan mengatasi masalah.


Anda harus menggunakan find -maxdepth 1untuk melakukan persis apa yang diminta OP tentang pengoperasian pada folder saat ini.
Caleb

1
Gunakan -depthopsi temukan , dan Anda dapat menyingkirkan sort.
glenn jackman

@glenn jackman: terima kasih, saya sekarang mengerti solusi saya salah.
enzotib

2
Ubah -name '* *'ke -name '*_*'dan ubah "${1// /_}"ke"${1//_/.}"
enzotib

1
@ kroiz: ini disebut "Substitusi pola". Anda dapat menemukannya di bashhalaman manual.
enzotib

34

Dalam shell apa pun, Anda dapat mengulang file yang namanya berisi spasi. Mengganti spasi dengan garis bawah mudah di bash, ksh dan zsh dengan ${VARIABLE//PATTERN/REPLACEMENT}konstruk.

for x in *" "*; do
  mv -- "$x" "${x// /_}"
done

Pada Debian, Ubuntu, dan turunannya, Anda dapat menggunakan Perl rename(distribusi lain mengirimkan program yang berbeda rename, dan program itu tidak membantu di sini).

rename 's/ /_/g' *

Solusi wajib zsh:

autoload zmv
zmv '(*)' '${1// /_}'

Solusi POSIX wajib:

for x in *" "*; do
  y=$(printf %sa "$x" | tr " " "_")
  mv -- "$x" "${y%a}"
done

Apa arti 'g' di akhir perintah "rename"? Saya tidak melihatnya di manual.
JulianLai

Bagaimana cara mengganti nama direktori saja? Saya tidak ingin mengubah nama file.
JulianLai

@JulianLai s/…/…/gberarti mengganti semua kejadian. Itu tidak dijelaskan dengan baik dalam manual . Jika Anda ingin mengganti nama direktori, ada beberapa cara, silakan mencarinya (saya pikir saya pernah melihatnya sebelumnya) dan jika Anda tidak dapat menemukannya, ajukan pertanyaan baru.
Gilles 'SANGAT berhenti menjadi jahat'

Hebat ... ini membantu saya mengubah nama semua _MG_blah.JPGmenjadi IMG_blah.JPG.
Abinash Dash

13

Anda dapat menggunakan renameini (dengan asumsi dari util-linux, bukan dari perl):

cd /path/to/dir
rename ' ' _ *\ *

Ini akan menemukan semua file dan direktori ruang dalam nama dan mengganti ruang dengan garis bawah. Karena menggunakan pencocokan file glob, Anda harus berada di direktori yang benar untuk memulainya.

Jika Anda ingin melakukan pertandingan rekursif Anda bisa, tetapi Anda mungkin harus melakukan renamebeberapa kali untuk menangkap item dalam direktori yang namanya diubah sendiri:

cd /path/to/dir
shopt -s globstar
rename ' ' _ **/*\ *
!!; !!

2
" renameAkan mengganti nama file yang ditentukan dengan mengganti kemunculan pertama dari dalam nama mereka dengan ke ." Jadi ini hanya akan bekerja untuk file dengan satu spasi dalam nama mereka. (Anda bisa menelepon renamedalam satu lingkaran, tapi itu bukan alat yang tepat di sini.)
Gilles 'SO- stop being evil'


1

Di Debian / Ubuntu, membangun berdasarkan jawaban Caleb dan Gilles, inilah yang berhasil bagi saya untuk mengubah nama file secara rekursif:

cd /path/to/dir
shopt -s globstar
rename 's/ /_/g' **

Catatan: Untuk melihat pratinjau file apa yang akan diubah namanya dan caranya, gunakan -nsakelar dengan rename:

rename -n 's/ /_/g' **

Catatan lain: pengaturan globstarmembuat **file yang cocok di semua subdirektori, jadi jika hanya direktori saat ini yang diinginkan, jangan tetapkan globstar atau gunakan *sebagai gantinya **.

Satu catatan lagi: renamePerintah perlu dijalankan lebih dari sekali untuk file dengan banyak kemunculan istilah pencarian.


Itu hanya berfungsi jika direktori tidak mengandung spasi. (mengubah nama dari a b/c dke a_b/c_dtidak akan bekerja, Anda akan perlu pertama yang mengubah nama a b/c duntuk a b/c_d, dan kemudian a bke a_b).
Stéphane Chazelas

@Stephane: Apakah ini berarti menjalankan renameperintah yang sama dua kali?
Markus Pscheidt

Yah, lebih sering seperti ada tingkat direktori bersarang dengan spasi. Idealnya, Anda ingin melintasi kedalaman direktori terlebih dahulu, dan hanya mengkonversi nama file seperti dalam solusi yang diterima. Perhatikan juga bahwa bash **mengecualikan dotfile dan melintasi symlink.
Stéphane Chazelas

0

Jika Anda bukan flash pada ekspresi reguler (saya tidak!), Dan Anda dapat menjalankan aplikasi yang dirancang untuk KDE (baik Anda menggunakan desktop KDE - k atau Anda memiliki perpustakaan diinstal), maka krename adalah utilitas grafis yang hebat yang memungkinkan Anda melihat sebelum dan sesudah sebelum Anda berkomitmen pada perubahan. Ini memiliki sejumlah transformasi sederhana sebagai opsi dan juga mendukung ekspresi reguler. Anda bahkan dapat menggabungkan beberapa transformasi sekuensial menjadi satu penggantian nama sehingga Anda tidak perlu mendesain transformasi kompleks tunggal yang melakukan semuanya sekaligus. Ini juga memiliki opsi untuk terus mengubah nama file yang sama setelah nama telah diterapkan.

Saya tidak menggunakannya sesering itu, tetapi ketika saya melakukannya, itu benar-benar menyelesaikan pekerjaan dengan cepat dan mudah. Ini sangat berguna ketika mengganti nama berbagai file media yang diunduh sehingga Anda dapat mengelolanya secara seragam di sistem Anda. Membantu mengunduh manual krename secara terpisah sehingga Anda dapat merujuknya saat menggunakan program.

http://www.krename.net/

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.