Jadi, saya sangat tidak sabaran menggunakan skrip berikut di server 19,04 saya dalam upaya untuk memindahkan banyak file video ke folder dengan awalan:
dirs=(A B C D E F G H I J K L M N O P Q R S T U V W X Y Z)
shopt -s nocasematch
for file in *
do
for dir in "${dirs[@]}"
do
if [ -d "$file" ]; then
echo 'this is a dir, skipping'
break
else
if [[ $file =~ ^[$dir] ]]; then
echo "----> $file moves into -> $dir <----"
mv "$file" "$dir"
break
fi
fi
done
done
Tidak ada petunjuk di mana ia salah, tetapi alih-alih memindahkan file ke folder, ia pergi ke output tunggal .. jadi:
----> a1.ts moves into -> A <----
----> a2.ts moves into -> A <----
----> a3.ts moves into -> A <----
----> a4.ts moves into -> A <----
----> a5.ts moves into -> A <----
----> c1.ts moves into -> C <----
----> c2.ts moves into -> C <----
----> c3.ts moves into -> C <----
----> c4.ts moves into -> C <----
----> c5.ts moves into -> C <----
Untungnya saya menghentikan proses (CTRL + C) segera setelah saya perhatikan itu tidak berjalan seperti yang dimaksudkan dan tidak pergi melalui seluruh folder.
Jadi sekarang saya punya file-file itu A
dan C
, yang kurang dari Gb, dan sepertinya itu adalah video TUNGGAL.
Ada 50Gb yang tidak terhitung dalam penggunaan total disk folder itu sendiri, tetapi ruang disk keseluruhan komputer tetap sama. Membuat saya berpikir file tidak terhapus?
Setiap bantuan dihargai, terima kasih :)
Sunting: file-file tersebut benar-benar hilang, hanya file terakhir yang tersisa, semua yang diperlukan adalah beberapa waktu untuk disk menggunakan info untuk memperbarui .. moral dari cerita, jalankan skrip Anda pada file tiruan sebelumnya!
sumber
A
,B
dan seterusnya ada sebelum menjalankan skrip? Jika tidak, Anda baru saja mengganti nama file. Semua file yang namanya dimulaia
atauA
diubah namanyaA
, sehingga hanya file yang diganti namanya terakhir yang bertahan, yang lain ditimpa. Untuk memanggil variabeldir
tidak membuat direktori!mv "$file" "$dir/"
, dengan trailing/
; maka jika$dir
tidak ada,mv
akan kesalahan bukannya ganti nama$file
menjadi$dir
. Juga pertimbangkanmv -i
danmv -n
. Dan selalu lakukanmkdir -p
sebelum bergerak, untuk ukuran yang baik.Jawaban:
Saya pikir ini masalahnya: Anda seharusnya membuat direktori A, B, C ... Z. Jika Anda melakukannya,
mv
perintahnya harus memindahkan file ke direktori tersebut.Tetapi jika tidak,
mv
perintah memindahkan file ke file dengan nama-nama itu, A, B, C ... dan saya pikir ini yang Anda lakukan.Untuk membuat shellscript lebih aman, Anda harus membuatnya membuat direktori (jika belum ada) sebelum Anda mulai bergerak.
Jika Anda ingin hal untuk mendapatkan bahkan lebih aman, Anda juga dapat menggunakan
mv
dengan-i
opsisumber
touch
akan menjadi pengganti yang baikmkdir
untuk menghindari konflik jika menjalankan skrip beberapa kali?touch
membuat file jika nama tidak ada. Jadi tidak akan melakukan apa yang Anda inginkan dalam hal ini.mkdir -p
dapat menangani menggunakan skrip beberapa kali.mv
lebih aman adalah dengan membiasakan menambahkan garis miring pada nama target ketika targetnya adalah direktori yaitumv "$file" "$dir/"
@Sudodus sudah menjelaskan apa yang salah, tapi inilah versi skrip Anda yang lebih sederhana untuk kali berikutnya:
Penjelasan
for letter in {a..z}; do
:{a..z}
meluaskan ke semua huruf kecil antaraa
danz
:Jadi ini akan mengulangi semua huruf kecil, menyimpan masing-masing sebagai
$letter
.dir=${letter^}
: sintaks${var^^}
mengembalikan konten variabel$var
dengan karakter pertama dalam huruf besar (karena ini hanya memiliki satu karakter, itu saja yang kita butuhkan). Jadi, jika$letter
inia
, maka${letter^^}
adalahA
, dan karena itu$dir
akan menjadi versi huruf dari saat ini$letter
.mkdir -p -- "$dir"
: buat direktori. Jika sudah ada, jangan lakukan apa-apa (-p
). The--
menandakan akhir pilihan , dan berguna untuk melindungi nama dimulai dengan-
.mv -- "$letter"* "${letter^}"* "$dir"
: pindahkan setiap file (atau direktori) ke target yang relevan.Masalahnya, ini juga akan memindahkan direktori yang mungkin Anda miliki. Itu tidak akan memindahkan direktori target, karena mereka belum ada, atau Anda akan mencoba memindahkannya ke direktori mereka sendiri, tetapi direktori yang ada yang bukan direktori target akan dipindahkan.
Jika itu masalah, Anda harus melakukan sesuatu seperti ini:
sumber
${letter^}
dan${letter^^}
, dan jika keduanya identik, mengapa digunakan${letter^^}
sebagai ganti$dir
?${var^}
hanya menggunakan huruf besar untuk huruf pertama, sedangkan${var^^}
huruf besar untuk semua huruf. Tidak ada bedanya di sini karena$letter
hanya memiliki satu huruf.$dir
padamv
perintah. (Dalam bentuknya sekarang ini akan gagal jika file sudah ada sebelumnya dengan nama huruf tunggal)Alih-alih memeriksa setiap file terhadap array kamus yang menciptakan banyak iterasi Anda dapat mencocokkan file dengan pola.
Sortir yang sangat mendasar:
sumber
Lindungi di .bashrc Anda:
sumber
-n Do not overwrite an existing file. (The -n option overrides any previous -f or -i options.)
demikian, tidak jadi masalah bahwa tag -n adalah sebelum mengikuti tag? The = --backup bernomor akan membuat ganda masing-masing benar, bukankah itu (terabyte berbicara) agak berlebihan (dan ruang energi / memakan) ketika berhadapan dengan file video uber-besar. Terima kasih!Sebagai catatan, beberapa cara untuk berhenti
mv
menimpa file yang ada:Jika Anda ingin pindah ke direktori, tambahkan garis miring ke target, yaitu gunakan
mv "$file" "$dir"/
alih-alihmv "$file" "$dir"
. Jika$dir
tidak ada atau tidak direktori,mv
akan mengeluh:Ini sepertinya membuat system call
rename("a", "z/")
, jadi itu harus aman dari kerentanan waktu-ke-waktu-ke-waktu-penggunaan, jika seseorang menangani set file yang sama pada waktu yang sama.Atau, gunakan
mv -t "$dir" "$file"
. Sekali lagi, itu akan mengeluh jika$dir
bukan direktori.Gunakan
-n
opsi untuk mencegah menimpa file yang ada:Itu tidak akan menghentikannya mengubah nama file pertama, tetapi kemudian tidak akan membuangnya dengan yang lain.
Sepertinya ini panggilan biasa
rename()
, jadi mungkin tidak aman dengan penanganan simultan. (Adarenameat2()
yang akan mendukung bendera untuk mencegah penulisan ulang.)sumber
Meskipun tampaknya tidak demikian bagi Anda, ada kemungkinan Anda bisa melakukan ini dan tidak kehilangan file. Ini akan membutuhkan satu dari dua hal untuk menjadi kenyataan:
Sistem file Unix memungkinkan lebih dari satu entri direktori untuk merujuk ke konten file yang sama persis . Ini disebut ' tautan keras '. Anda dapat membuat tautan keras dengan
ln
perintah, tanpa opsi umum-s
(lunak / simbolik). Selama setidaknya ada satu tautan keras ke konten file, itu tidak akan digunakan kembali oleh sistem file.(Catatan samping, izin biasanya berlaku untuk konten file, bukan ke entri direktori. Inilah sebabnya mengapa pengguna biasa terkadang dapat menghapus file yang dimiliki oleh
root
, tetapi tidak menulisnya. Operasi penghapusan memodifikasi folder, bukan file itu sendiri. )Sistem file juga tidak akan menggunakan kembali konten file selama setidaknya satu proses membuka file. Bahkan jika tidak ada entri direktori, sistem file tidak akan menganggap ruang menjadi bebas sampai tidak ada proses yang terbuka. File dapat dipulihkan dari virtual filesystem
/proc/<pid>/fd
olehroot
asalkan file tersebut tetap terbuka. (Terima kasih @fluffysheap.)sumber