Saya ingin mengubah nama semua file dan folder (sub-folder) secara rekursif menjadi huruf besar.
Saya menemukan beberapa skrip yang akan melakukannya menjadi huruf kecil, tetapi saya tidak tahu bagaimana mengubahnya sehingga akan melakukannya sebaliknya (lebih rendah ke atas).
Skrip yang saya temukan dan berfungsi untuk huruf kecil, tetapi saya tidak tahu cara memodifikasi adalah:
rename 'y/A-Z/a-z/' *
Itu dari man rename
.
rename 'y/a-z/A-Z/' *
Anda akan mendapatkan apa yang Anda inginkan. Hati-hati saat Anda mengujinya.Jawaban:
Perhatikan bahwa Anda menggunakan skrip Perl yang disebut
rename
didistribusikan oleh Debian dan turunannya (Ubuntu, Mint, ...). Distribusi Linux lainnya mengirimkan perintah yang sama sekali berbeda, dan sangat tidak berguna, disebutrename
.y/A-Z/a-z/
menerjemahkan setiap karakter dalam kisaranA
melaluiZ
ke dalam sesuai karakter dalam kisarana
melaluiz
, yaitu ASCII huruf besar huruf ke huruf kecil yang sesuai. Untuk melakukan terjemahan yang berlawanan, gunakany/a-z/A-Z/
. Cara lain untuk menulis perintah yang sama adalahrename '$_ = uc($_)' *
-uc
adalah fungsi u pper c ase, danrename
perintah mengganti nama file berdasarkan transformasi yang dibuat ke$_
variabel.rename '…' *
hanya mengganti nama file di direktori saat ini, karena itulah yang*
cocok. File dot (file yang namanya dimulai dengan.
) dilewati juga.Jika Anda ingin mengganti nama file di direktori saat ini dan di subdirektori secara rekursif, Anda dapat menggunakan
find
perintah untuk melintasi direktori saat ini secara rekursif. Ada kesulitan di sini: jika Anda meneleponrename
, ini mengganti nama direktori dan bagian nama dasar. Jika Anda memanggilrename
direktori sebelum berulang ke dalamnya (find -exec rename … {} \;
),find
menjadi bingung karena menemukan direktori tetapi direktori itu tidak ada lagi pada saat ia mencoba turun ke dalamnya. Anda bisa menyiasatinya dengan mengatakanfind
untuk melintasi direktori sebelum bertindak di atasnya, tapi kemudian Anda berakhir mencoba untuk mengubah namafoo/bar
keFOO/BAR
tetapi direktoriFOO
tidak ada.Cara sederhana untuk menghindari kesulitan ini adalah membuat perintah pengubahan nama hanya bertindak pada bagian nama dasar dari path. Ekspresi reguler
([^/]*\Z)
cocok dengan bagian akhir dari jalur yang tidak mengandung a/
.Shell zsh menyediakan fitur yang lebih nyaman untuk penggantian nama - bahkan lebih samar dari Perl, tetapi lebih singkat dan seringkali lebih mudah untuk dikomposisi.
Fungsi
zmv
mengubah nama file berdasarkan pola. Jalankanautoload -U zmv
sekali untuk mengaktifkannya (masukkan baris ini di Anda.zshrc
).Dalam argumen pertama ke
zmv
(pola untuk mengganti), Anda dapat menggunakan pola wildcard zsh yang kuat . Dalam argumen kedua kezmv
(teks pengganti), Anda dapat menggunakan fitur ekspansi parameternya , termasuk pengubah riwayat .Penjelasan:
-w
- Otomatis menetapkan variabel numerik untuk setiap pola wildcard**/*
- semua file dalam subdirektori, secara rekursif (**/
cocok dengan 0, 1 atau lebih level subdirektori)$1
- variabel numerik pertama, di sini cocok dengan bagian direktori dari setiap jalur$2:u
- variabel numerik kedua, di sini mencocokkan bagian nama dasar dari setiap jalur, dengan:u
pengubah untuk mengkonversi nilai menjadi huruf besarSebagai bonus tambahan, ini menghormati pengaturan lokal sekitar.
Jika Anda tidak yakin tentang
zmv
perintah yang Anda tulis, Anda dapat memberikan-n
opsi untuk mencetak apa yang akan dilakukan perintah dan tidak mengubah apa pun. Periksa output, dan jika itu melakukan apa yang Anda inginkan, jalankan kembali perintah tanpa-n
benar-benar bertindak.sumber
Dicuri (dengan suntingan kecil) dari posting Gilles di sini
find <DIR> -depth -type d -exec rename -n 's!/([^/]*/?)$!\U/$1!' {} +
sumber
find <dir> -exec rename 'y/a-z/A-Z/' {} \;
find
sedang berulang ke dalamnya.find <dir> -depth -exec rename 'y/a-z/A-Z/' {} \;
harus menangani masalah penggantian nama direktori. Benar?rename
perubahan misalnyafoo/bar
keFOO/BAR
danFOO
tidak ada pada saat itu.Saya ingin mengarahkan siapa pun yang masih terkait dengan jawaban ini ke jawaban luar biasa yang diberikan Guiles Quernot untuk pertanyaan ini yang tidak diperlukan
find
.Perintah yang dihasilkan adalah:
Tetapi sebelum menjalankan silakan baca jawaban yang terhubung untuk peringatan tentang versi bash lama.
Akhirnya kalau-kalau ada yang bertanya-tanya apa yang dilakukan
y///
perintahperl regex
. Berikut tautan ke dokumentasi yang relevan .sumber
find -execdir
| ganti namaIni akan menjadi cara terbaik untuk melakukannya jika bukan karena kegilaan jalur relatif, karena ia menghindari Perl regex fu untuk hanya bertindak berdasarkan nama:
-execdir
pertama-tamacd
masuk ke direktori sebelum mengeksekusi hanya pada nama bas.Sayangnya, saya tidak dapat menyingkirkan
PATH
bagian peretasan itu,find -execdir
menolak melakukan apa pun jika Anda memiliki jalur relatif diPATH
...: /ubuntu/621132/why-using-the-execdir-action- is-insecure-for-direktori-which-is-in-the-path / 1109378 # 1109378sumber
Coba ini setelah pindah ke direktori tempat Anda ingin mengganti nama file:
sumber
ls -l
hanya menjalankan untuk memotong kolom selain nama?), Dan menggunakan tanda kutip ganda di sekitar substitusi variabel . Kode Anda terlalu rumit dan terpecah pada nama file yang mengandung spasi dan karakter khusus lainnya. Gunakanfind
atau**/
untuk kembali ke subdirektori, outputls
hanya untuk konsumsi manusia.