Saya folderA
memiliki beberapa file dengan urutan angka yang dimulai dengan a_000000
. Yang ingin saya lakukan adalah menghapus file mulai dari nomor tertentu: katakanlah a_000750
sampai akhir file dalam hal ini folderA
. Adakah yang bisa menyarankan bagaimana melakukan ini menggunakan skrip shell?
16
rm a_000[89]* a_0007[5-9]*
?a_000[89]*
mencakup setiap file yang diawali dengana_0008
ataua_0009
, dana_0007[5-9]*
termasuk setiap file yang diawali dengana_0007
dan kemudian berisi angka antara 5 dan 9, diikuti oleh apa pun.Jawaban:
Dengan asumsi Anda tahu atau bisa menebak akhir kisaran, Anda bisa menggunakan ekspansi brace :
Di atas akan menghapus 101 file antara a_000750 dan a_000850 inklusif (dan mengeluh tentang nama file yang merujuk ke file yang tidak ada). Jika Anda memiliki terlalu banyak file untuk itu, gunakan
find
:Di sini,
find
cukup daftar semua file yang cocoka_*
. Daftar ini diteruskan kewhile
loop di mana setiap nama file dibaca ke dalam variabel$file
. Kemudian, dengan menggunakan fitur manipulasi string bash , jika bagian numeriknya (cari mencetak file sebagai./file
, jadi${file#./a_}
cetak nomornya saja)000750
atau lebih besar, file tersebut dihapus. The-v
hanya ada sehingga Anda dapat melihat file apa yang telah dihapus.Perhatikan bahwa di atas mengasumsikan nama file yang waras. Jika nama Anda dapat memiliki spasi, baris baru atau karakter aneh lainnya, gunakan ini sebagai gantinya:
sumber
[[
?[[
misalnya tidak menyederhanakan hal-hal di sini[[ "${file#./a_}" > 000749 ]]
, bahkan tidak membuatnya lebih pendek. Saya tidak suka menggunakan sintaks yang tidak perlu dan ini bahkan akan bekerja di shell yang lebih sederhanadash
.[[
menangani ruang dan keanehan lebih baik (saya tidak terlalu peduli untuk>
keduanya).[
tidak masalah jika Anda mengutip variabel yang saya miliki, bekerja pada shell yang jauh lebih sederhana dan lebih sederhana.Anda dapat melakukan sesuatu seperti ini:
Atau:
Metode pertama mengasumsikan awalan tetap, menghapusnya dan memeriksa nilainya.
Metode kedua mengasumsikan sufiks dengan panjang tetap (dan awalan tetap umum) dan bergantung pada fakta itu; dan itu, sementara
201
datang sebelum31
secara leksikografis, itu tidak terjadi sebelumnya031
.Uji ini dengan
echo
perintah, dan setelah Anda yakin itu daftar file yang benar, gunakanrm
saja.sumber
Solusi shell POSIX
Solusi pertama terdon bergantung pada ekspansi brace, yang merupakan properti dari ,
bash
danksh
bagaimanapun itu tidak dapat digunakan dalam/bin/sh
shell standar , yang pada Ubuntu disinkronkan dengan/bin/dash
.Dalam kasus di mana Anda harus mengandalkan
/bin/sh
portabilitas skrip Anda, umumnya ada dua cara untuk mendekati ini. Seseorang akan melalui globbing. Hanyacd folderA
dan dari sana larirm a_*
. Cara lain, akan menerapkan C-style untuk alternatif loop menggunakanwhile <CONDITION>;do ...done
dalam bahasa shell dan memformat angka denganprintf
:Perhatikan bahwa di sini saya gunakan
echo
. Gantiecho "$filename"
denganrm ./"$filename"
ataurm -- "$filename"
ketika Anda siap untuk menghapus file. Perhatikan juga, bahwa ini harus dilakukan ketika Anda sudahcd
masuk ke direktori yang diinginkan.(ab) menggunakan awk
Awk menjadi bahasa mirip-C yang bagus dapat membantu kita dalam dua cara: (1) kita dapat menghasilkan nama file dengan for-loop dan memformatnya melalui
sprintf
fungsi, dan (2) menghapus file tersebut melaluisystem()
perintah, yang akan melewati nama file danrm
perintah yang dihasilkan untuk/bin/sh
:Perl
Melanjutkan dengan gagasan pendekatan portabel di mana kita "menghasilkan" nama file, kita dapat melakukan hal yang sama di Perl:
sumber
Sesederhana
Dalam contoh Anda itu
sumber
a_00075
...