Saya ingin huruf kecil setiap nama direktori di bawah direktori. Dengan perintah apa saya bisa melakukan itu?
sumber
Saya ingin huruf kecil setiap nama direktori di bawah direktori. Dengan perintah apa saya bisa melakukan itu?
Semua direktori pada satu level, atau secara rekursif?
Pada satu tingkat:
autoload zmv
zmv -o-i -Q 'root/(*)(/)' 'root/${1:l}'
Secara rekursif:
zmv -o-i -Q 'root/(**/)(*)(/)' 'root/$1${2:l}'
Penjelasan: zmv
mengganti nama file yang cocok dengan pola sesuai dengan teks pengganti yang diberikan. -o-i
melewati -i
opsi untuk setiap mv
perintah di bawah tenda (lihat di bawah). Dalam teks pengganti, $1
, $2
, dll, adalah kelompok kurung berturut-turut dalam pola. **
berarti semua (sub) * direktori, secara rekursif. Final (/)
bukan grup kurung tetapi kualifikasi global yang berarti hanya cocok dengan direktori. ${2:l}
dikonversi $2
ke huruf kecil.
Pada satu tingkat:
for x in root/*/; do mv -i "$x" "$(printf %s "$x" | tr '[:upper:]' '[:lower:]')"; done
Final /
membatasi pencocokan ke direktori, dan mv -i
membuatnya meminta konfirmasi jika terjadi tabrakan. Hapus -i
untuk menimpa jika terjadi tabrakan, dan gunakan yes n | for …
. untuk tidak diminta dan tidak melakukan penggantian nama yang akan bertabrakan.
Secara rekursif:
find root/* -depth -type d -exec sh -c '
t=${0%/*}/$(printf %s "${0##*/}" | tr "[:upper:]" "[:lower:]");
[ "$t" = "$0" ] || mv -i "$0" "$t"
' {} \;
Penggunaan -depth
memastikan bahwa direktori yang sangat bersarang diproses sebelum leluhur mereka. Pemrosesan nama bergantung pada ada /
; jika Anda ingin memanggil operasi di direktori saat ini, gunakan ./*
(mengadaptasi skrip shell untuk mengatasi .
atau*
dibiarkan sebagai latihan untuk pembaca).
Di sini saya menggunakan skrip rename Perl yang dikirimkan oleh Debian dan Ubuntu /usr/bin/prename
(biasanya juga tersedia rename
). Pada satu tingkat:
rename 's!/([^/]*/?)$!\L/$1!' root/*/
Secara rekursif, dengan bash ≥4 atau zsh:
shopt -s globstar # only in bash
rename 's!/([^/]*/?)$!\L/$1!' root/**/*/
Secara rekursif, mudah dibawa:
find root -depth -type d -exec rename -n 's!/([^/]*/?)$!\L/$1!' {} +
mv -i a a
beri "mv: ganti nama a menjadi a / a: Argumen tidak valid".-execdir
yang luar biasa: unix.stackexchange.com/questions/5412/... Saya kemudian menemukan bahwa ia memiliki beberapaPATH
kegilaan dan sedih :-(Tidak ada satu perintah pun yang akan melakukan itu, tetapi Anda dapat melakukan sesuatu seperti ini:
Jika Anda ingin menjadi kuat, Anda harus memperhitungkan ketika sudah ada dua direktori yang hanya berbeda dalam kasus.
Sebagai one-liner:
sumber
for file in * ; do if [ -d "$file" ] ; then dest="$(echo $file | sed y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/)" ; [ "$dest" != "$file" ] && mv "$file" "$dest" ; fi ; done
find -type d
, tetapi tidak bisa mendapatkannyafor fd in */;
, sehingga menghindari perlunya memeriksa apakah itu direktori, tapi saya tidak tahu apakah insting ini bagus.tr
sudah mengharapkan suatu range, sehinggatr '[A-Z]' '[a-z]'
diterjemahkan[
ke[
dan]
untuk]
di lewat. Ini tidak berguna tetapi tidak berbahaya; namun tanpa tanda kutip shell akan memperluas tanda kurung jika ada file dengan nama satu huruf besar di direktori saat ini.Saya menganggap ini sebagai tantangan satu-lapis :) Pertama, buat uji kasus:
Saya menggunakan
find
untuk melihat direktori dengan huruf besar dan kemudian menurunkannya . Tebak menggunakan agak hack-ish, tapi kepalaku selalu meledak ketika aku mencoba melarikan diri secara langsung.sh -c 'mv {}
echo {} | tr [:upper:] [:lower:]
'sh -c
find
Berhati-hatilah: Solusi ini tidak memeriksa apakah downcasing mengarah ke tabrakan!
sumber
mv -i
. Masalah yang lebih besar adalah bahwa Anda belum menggunakan kutipan yang tepat, sehingga perintah Anda akan gagal jika ada karakter khusus (spasi putih atau\[*?
) di mana saja dalam nama. Tidak ada gunanya menggunakanfind
kecuali berulang, dan kemudian Anda perlufind -depth
, dan-path
harus-name
. Lihat jawaban saya untuk contoh kerja.mv -i
setelah menulis ini. Poin yang bagus dengan kutipan ...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 hanya mengeksekusi pada nama samaran.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