$ i=0;$((i++))$ echo $i1$biarkan i++$ echo $i2$expr $i + 13$ echo $i2$ echo $i 1 | awk '{printf $1+$2}'3
menjelaskan:
exprsetelah
$i,
+, 1 dipisahkan dengan spasi. Jika perkalian dilakukan, operator harus di-escape, jika tidak, Shell akan menafsirkan tanda perkalian sebagai karakter wildcard, yang mengakibatkan kesalahan sintaksis;
awkdi belakang
$1Dan
$2masing-masing mengacu pada
$idan 1 yaitu angka ke-1 dan ke-2 dari kiri ke kanan.
Gunakan perintah bawaan Shell untuk melihat tipe setiap perintah sebagai berikut:
$ tipe typetype adalah shell bawaan$ tipe letlet adalah shell bawaan$ tipe exprexpr di-hash (/usr/bin/expr)$ tipe bcbc di-hash (/usr/bin/bc)$ tipe awkawk adalah /usr/bin/awk
Hal ini dapat dilihat dari demonstrasi di atas:
membiarkanIni adalah perintah bawaan Shell, dan beberapa perintah lainnya adalah perintah eksternal, semuanya ada di dalamnya
/usr/bindirektori. Dan
exprDan
SMKarena baru dipakai, sudah dimuat ke dalam memori.
hashmeja. Ini akan membantu kita memahami prinsip di balik berbagai metode eksekusi skrip yang diperkenalkan pada bab sebelumnya.
Catatan: Jika Anda ingin melihat bantuan untuk perintah yang berbeda, misalnya
membiarkanDan
jenisMenunggu perintah bawaan Shell, Anda dapat menggunakan perintah bawaan Shell
membantuuntuk melihat bantuan terkait, dan beberapa perintah eksternal dapat diakses melalui perintah eksternal Shell
priauntuk melihat bantuan, penggunaan seperti
bantu biarkan,
manexprTunggu.
#!/bin/bash# calc.shi=0;sementara [ $i -lt 10000 ]lakukan ((i++)) selesaieecho $i
Deskripsi: Lewat sini
sementara [ekspresi kondisional]; lakukan .... selesaiSiklus untuk mencapai.
-ltkurang dari tanda
<, lihat detailnya
tesPenggunaan perintah:
tes manusia.
Bagaimana cara menjalankan skrip ini?
Metode 1: Langsung meneruskan file skrip sebagai parameter sub-Shell (Bash)
$ bash calc.sh$ ketik bashbash di-hash (/bin/bash)
Metode 2: Lulus
pestaperintah bawaan
.atau
sumbermelaksanakan
$ ./kalk.sh
atau
$ source ./calc.sh$ type .. adalah shell bawaan$ type sourcesource adalah shell bawaan
Metode 3: Ubah file agar dapat dieksekusi dan jalankan langsung di bawah Shell saat ini
$ chmod ./calc.sh $ ./calc.sh
Selanjutnya kita akan mendemonstrasikan satu per satu penggunaan metode lain untuk menghitung variabel plus satu, yaitu,
((saya++))sejalan dengan salah satu dari berikut ini:
biarkan i++;i=$(expr $i + 1)i=$(echo $i+1|bc)i=$(echo $i 1 | awk '{printf $1+$2;}')
Perbandingan waktu perhitungannya adalah sebagai berikut:
$ waktu calc.sh10000real 0m1.319suser 0m1.056ssys 0m0.036s$ waktu calc_let.sh10000real 0m1.426suser 0m1.176ssys 0m0.032s$ waktu calc_expr.sh1000real 0m27.425suser 0m5.060ssys 0m14.177s$ waktu calc_bc.sh1000real 0m56.576suser 0m9.353ssys 0m24.618s$ waktu ./calc_awk.sh100real 0m11.672suser 0m2.604ssys 0m2.660s
menjelaskan:
waktuPerintah ini dapat digunakan untuk menghitung waktu eksekusi perintah. Bagian waktu ini mencakup total waktu berjalan, waktu eksekusi ruang pengguna, dan waktu eksekusi ruang kernel
ptraceImplementasi panggilan sistem.
Melalui perbandingan di atas dapat diketahui bahwa
(())memiliki efisiensi operasional tertinggi. Dan
membiarkanSebagai perintah bawaan Shell, ini juga sangat efisien, namun
expr,
SM,
awkEfisiensi perhitungannya relatif rendah. Oleh karena itu, jika Shell sendiri dapat menyelesaikan pekerjaan yang relevan, disarankan untuk mengutamakan fungsi yang disediakan oleh Shell itu sendiri. Namun ada fungsi yang tidak dapat diselesaikan oleh Shell sendiri, seperti operasi floating point, sehingga diperlukan bantuan perintah eksternal. Selain itu, mengingat portabilitas skrip Shell, jangan gunakan sintaks khusus Shell tertentu ketika kinerja tidak penting.
membiarkan,
expr,
SMdapat digunakan untuk mencari modulo, dan operatornya semuanya
%,Dan
membiarkanDan
SMDapat digunakan untuk mencari eksponensial. Operatornya berbeda
**, yang terakhir adalah
^. Misalnya:
$ expr 5 % 21$ biarkan i=5%2$ gema $i1$ gema 5 % 2 | bc1$ ((i=5%2))$ gema $i1
$ biarkan i=5**2$ gema $i25$ ((i=5**2))$ gema $i25$ gema 5^2 |
Konversi basis juga merupakan operasi yang relatif umum yang dapat Anda gunakan
PestaDukungan bawaan untuk
SMUntuk menyelesaikan, misalnya, mengonversi 11 dari oktal ke desimal, Anda dapat:
$ gema obase=10;ibase=8;11 |.bc -l9$ gema $((8#11))9
Semua cara di atas mengubah bilangan dalam sistem basis tertentu menjadi basis 10. Jika Anda ingin mengkonversi antara sistem basis apa pun, tetap saja
SMLebih fleksibel karena bisa langsung digunakan
ibaseDan
obaseTentukan masing-masing sumber dasar dan target konversi dasar.
Jika Anda ingin mengekspresikan beberapa string dalam basis tertentu, Anda dapat menggunakan
odperintah, seperti pemisah default
JIKAtermasuk spasi,
TABSelain jeda baris, Anda dapat menggunakannya
pria asciibukti.
$ gema -n $IFS |.od -c0000000 t n0000003$ gema -n $IFS |.od -b0000000 040 011 0120000003
membiarkanDan
exprNamun, tidak ada yang bisa melakukan operasi floating point
SMDan
awkBisa.
$ skala gema=3; 13/1 |.bc.076$ gema 1 13 |.awk '{printf(%0.3fn,$1/$2)}'0,077
menjelaskan:
SMPresisi perlu ditentukan saat melakukan operasi floating point, jika tidak maka defaultnya adalah 0, yaitu saat melakukan operasi floating point, hasil default hanya mempertahankan bilangan bulat. Dan
awkSangat fleksibel ketika mengontrol jumlah tempat desimal, hanya dengan
printfKontrol format dapat dicapai.
Tambahan: Sedang digunakan
SMSaat melakukan operasi, jika tidak digunakan
skalaTentukan presisi saat masuk
SMtambahkan setelahnya
-lpilihan, operasi floating point juga dapat dilakukan, tetapi presisi default saat ini adalah 20 digit. Misalnya:
$ gema 1/13100 |.bc -l.00007633587786259541
menggunakan
SM -lPerhitungan dapat mencapai akurasi yang tinggi:
$ ekspor cos=0,996293; skala gema=100; a(sqrt(1-$cos^2)/$cos)*180/(a(1)*4) | -l4.9349547554113836327198340369318406051597063986552438753727649177325495504159766011527078286004072131
Tentu saja bisa juga digunakan
awkUntuk menghitung:
$ gema 0,996293 |.awk '{ printf(%sn, atan2(sqrt(1-$1^2),$1)*180/3.1415926535);}'4.93495
Satu set data uji dihasilkan secara acak di sini, dan nama filenya adalah
pendapatan.txt.
1 3 44902 5 38963 4 31124 4 47165 4 45786 6 53997 3 50898 6 30299 4 619510 5 5145
Catatan: Tiga kolom data di atas adalah nomor keluarga, jumlah anggota keluarga, dan jumlah pendapatan keluarga bulanan.
Analisis: Untuk mencari keluarga dengan rata-rata pendapatan bulanan tertinggi, Anda perlu membagi dua kolom berikut, yaitu mencari rata-rata pendapatan bulanan setiap keluarga, kemudian mengurutkan berdasarkan rata-rata pendapatan bulanan untuk mencari keluarga dengan pendapatan tertinggi.
menyelesaikan:
#!/bin/bash# gettopfamily.sh[ $# -lt 1 ] && echo silakan masukkan file pendapatan && exit -1[ ! -f $1 ] && echo $1 bukan file && exit -1income=$1awk '{ printf(%d %0.2fn, $1, $3/$2);}' $pendapatan | sortir -k 2 -n -r
menjelaskan:
[ $# -lt 1 ]: Membutuhkan setidaknya satu parameter untuk dimasukkan,
$#Apakah jumlah parameter yang diteruskan di Shell
[ ! -f $1 ]: Membutuhkan parameter input berupa file,
-FUntuk penggunaan, lihat
tesMemesan,
tes manusia
pendapatan=$1: Tetapkan parameter masukan ke variabel pendapatan, lalu gunakan sebagai
awkparameter, yaitu file yang akan diproses
awk: Bagilah kolom ketiga file dengan kolom kedua untuk menemukan pendapatan bulanan rata-rata. Dengan mempertimbangkan keakuratan, dua digit presisi dipertahankan.
urutkan -k 2 -n -r:Inilah hasil dari
awkKolom kedua dari hasil
-k 2, yaitu rata-rata pendapatan bulanan diurutkan, diurutkan berdasarkan angka
-N, dan diurutkan dalam urutan menurun
-R.
Demo:
$ ./gettopfamily.sh pendapatan.txt7 1696.339 1548.751 1496.674 1179.005 1144.5010 1029.006 899.832 779.203 778.008 504.83
Tambahan: sebelumnya
pendapatan.txtData dihasilkan secara acak. Saat melakukan beberapa eksperimen, sering kali diperlukan untuk menghasilkan beberapa data secara acak. Pada bagian selanjutnya, kami akan memperkenalkannya secara detail. Di sini dihasilkan
pendapatan.txtSkrip data:
#!/bin/bash# genrandomdata.shuntuk saya di $(seq 1 10)lakukan echo $i $(($RANDOM/8192+3)) $((RANDOM/10+3000))selesai
Catatan: Juga digunakan dalam skrip di atas
seqPerintah ini menghasilkan kolom angka dari 1 hingga 10. Penggunaan rinci dari perintah ini akan diperkenalkan lebih lanjut di bagian terakhir artikel ini.
variabel lingkungan
ACAKHasilkan angka acak dari 0 hingga 32767, sementara
awkdari
acak()Fungsi tersebut dapat menghasilkan angka acak antara 0 dan 1.
$ gema $RANDOM81$ gema |.awk '{srand(); printf(%f, Rand());}'0.237788
menjelaskan:
pasir()Jika tidak ada parameter, waktu saat ini digunakan sebagai
acak()Generator nomor acak
benih.
bisa lewat
ACAKjumlah variabel yang berskala
awktengah
acak()untuk mencapai amplifikasi.
$ expr $RANDOM / 128$ echo |.awk '{srand(); printf(%dn, rand()*255);}'
Berpikir: Jika Anda ingin membuat alamat IP secara acak untuk segmen IP tertentu, bagaimana cara melakukannya? Lihat contoh: Ramah mendapatkan alamat IP yang dapat digunakan.
#!/bin/bash# getip.sh -- dapatkan alamat ipad yang dapat digunakan secara otomatis# penulis: falcon <[email protected]># update: Sel 30 Okt 23:46:17 CST 2007# atur jaringan Anda sendiri, gateway default , dan waktu habis ping commandnet=192.168.1default_gateway=192.168.1.1over_time=2# centang alamat ip saat ini -c 1 $default_gateway -W $over_time[ $? -eq 0 ] && echo alamat ip saat ini oke! && exit -1;sementara lakukan # hapus konfigurasi saat ini ifconfig eth0 down # konfigurasikan alamat ip eth0 ifconfig eth0 $net.$(($RANDOM /130 +2)) up # konfigurasi rute gateway default tambahkan default gw $default_gateway # centang konfigurasi baru ping -c 1 $default_gateway -W $over_time # jika berhasil, selesaikan [ $? -eq 0 ] && selesai
Catatan: Jika alamat gateway default Anda tidak
192.168.1.1, silakan konfigurasikan sendiri
default_gateway(dapat digunakan
rute-nperintah untuk melihat), karena menggunakan
ifconfigSaat mengonfigurasi alamat, Anda tidak dapat mengonfigurasinya sebagai alamat gateway, jika tidak, alamat IP Anda akan sama dengan gateway, menyebabkan seluruh jaringan tidak berfungsi dengan baik.
Faktanya, serangkaian angka dapat dihasilkan melalui satu putaran, tetapi mengapa tidak menggunakannya jika ada alat terkait!
seqIni adalah alat kecil yang dapat menghasilkan serangkaian angka. Anda dapat menentukan interval kenaikan angka, atau Anda dapat menentukan pemisah antara dua angka yang berdekatan.
$ seq 512345$ seq 1 512345$ seq 1 2 5135$ seq -s: 1 2 51:3:5$ seq 1 2 14135791113$ seq -w 1 2 1401030507091113$ seq -s: -w 1 2 1401:03:05:07:09:11:13$ seq -f 0x%g 1 50x10x20x30x40x5
Penggunaan yang lebih umum
seqMisalnya, buat beberapa tautan dalam format tertentu, lalu gunakan
wgetUnduh ini:
$ untuk saya di `seq -fhttp://thns.tsinghua.edu.cn/thnsebooks/ebook73/%02g.pdf 1 21`;lakukan wget -c $i;
atau
$ untuk saya di `seq -w 1 21`;lakukan wget -c http://thns.tsinghua.edu.cn/thnsebooks/ebook73/$i;
Tambahan: di
PestaVersi 3 ke atas, di
untukbundar
di dalamDi belakang, Anda bisa langsung lewat
{1..5}Lebih ringkasnya menghasilkan angka dari 1 sampai 5 (perhatikan hanya ada dua titik antara 1 dan 5), misalnya:
$ untuk saya di {1..5}; lakukan echo -n $i;
Pertama-tama mari kita berikan definisi sebuah kata: rangkaian karakter tunggal atau ganda yang terdiri dari huruf.
Pertama, hitung jumlah kemunculan setiap kata:
$ wget -c http://tinylab.org$ kucing indeks.html |.sed -es/[^a-zA-Z]/n/g |.grep -v ^$ |
Kemudian, hitung 10 kata teratas yang paling sering muncul:
$ wget -c http://tinylab.org$ cat index.html |.sed -es/[^a-zA-Z]/n/g |.grep -v ^$ | -k 1 -r |.head -10 524 a 238 tag 205 href 201 kelas 193 http 189 org 175 tinylab 174 www 146 div 128 judul
menjelaskan:
indeks kucing.html: Menampilkan konten file index.html
sed -es/[^a-zA-Z]/n/g: Ganti karakter non-abjad dengan spasi, simpan hanya karakter alfabet
grep -v ^$: menghapus baris kosong
menyortir: Urutkan
unik -c: Hitung jumlah baris yang sama, yaitu jumlah setiap kata
urutkan -n -k 1 -r: Menurut kolom pertama
-k 1nomor
-NUrutan terbalik
-Rmenyortir
kepala -10: Keluarkan sepuluh baris pertama
Dua pendekatan dapat dipertimbangkan:
Hitung saja kata-kata yang perlu dihitung
Gunakan algoritme di atas untuk menghitung jumlah semua kata, lalu mengembalikan kata yang perlu dihitung kepada pengguna
Namun, kedua metode tersebut dapat diterapkan melalui struktur berikut. Mari kita lihat metode pertama:
#!/bin/bash# statistic_words.shif [ $# -lt 1 ]; lalu echo Penggunaan: nama dasar $0 FILE WORDS .... exit -1fiFILE=$1((WORDS_NUM=$#-1))untuk n di $( seq $WORDS_NUM)lakukan shift cat $FILE |.sed -es/[^a-zA-Z]/n/g | ^$ |.urutkan |.grep ^$1$ |
menjelaskan:
jika kondisi bagian: Membutuhkan setidaknya dua parameter, file kata pertama, dan parameter selanjutnya adalah kata yang akan dihitung.
FILE=$1: Dapatkan nama file, yang merupakan string pertama setelah skrip
((WORDS_NUM=$#-1)): Dapatkan jumlah kata, yaitu jumlah total parameter
$#dikurangi parameter nama file (1)
untuk bagian lingkaran: Lulus dulu
seqMenghasilkan rangkaian angka kata yang perlu dihitung,
menggeseradalah variabel bawaan Shell (harap sampaikan
bantuan bergeserDapatkan bantuan), ini memindahkan parameter yang diteruskan oleh pengguna dari baris perintah ke belakang secara berurutan, dan menggunakan parameter saat ini sebagai parameter pertama.
$1, berlalu seperti ini
$1Anda dapat menelusuri semua kata yang dimasukkan oleh pengguna (jika Anda memikirkannya dengan cermat, sepertinya ini adalah subskrip array). Anda dapat mempertimbangkan
menggeserGantikan kalimat berikutnya dengan
gema $1tes
menggeserPenggunaan
Demo:
$ chmod +x statistic_words.sh$ ./statistic_words.sh index.html tinylab linux python 175 tinylab 43 linux 3 python
Mari kita lihat cara kedua, kita hanya perlu memodifikasinya
menggeserKalimat berikutnya sudah cukup:
#!/bin/bash# statistic_words.shif [ $# -lt 1 ]; lalu echo ERROR: Anda harus memasukkan minimal 2 kata; echo Penggunaan: nama dasar $0 FILE WORDS .... exit -1fiFILE=$1((WORDS_NUM= $#-1))untuk n di $(seq $WORDS_NUM)lakukan shift cat $FILE | -es/[^a-zA-Z]/n/g |.grep -v ^$ |. uniq -c |
Demo:
$ ./statistic_words.sh index.html tinylab linux python 175 tinylab 43 linux 3 python
Penjelasan: Tentu saja cara pertama jauh lebih efisien karena menemukan kata-kata yang perlu dihitung terlebih dahulu lalu menghitungnya, sedangkan cara kedua tidak. Faktanya, jika Anda menggunakan
memahamidari
-Epilihannya, kita tidak perlu memperkenalkan loop, tapi bisa melakukannya dengan satu perintah:
$ indeks kucing.html |.sed -es/[^a-zA-Z]/n/g |.grep -v ^$ |. grep -E ^tinylab$|^linux$ |
atau
$ indeks kucing.html |.sed -es/[^a-zA-Z]/n/g |.grep -v ^$ |.egrep ^tinylab$|^linux$ |
Deskripsi: Perlu diperhatikan
sedPerintah dapat memproses file secara langsung tanpa lewat
kucingOutput perintah kemudian dilewatkan melalui pipeline, yang dapat mengurangi operasi pipeline yang tidak diperlukan, sehingga perintah di atas dapat disederhanakan menjadi:
$ sed -es/[^a-zA-Z]/n/g indeks.html |.grep -v ^$ |.egrep ^tinylab$|^linux$ |
Jadi, dapat dilihat bahwa perintah-perintah ini
sed,
memahami,
unik,
menyortirBetapa bermanfaatnya mereka. Meski hanya menjalankan fungsi sederhana, melalui kombinasi tertentu, mereka dapat mencapai berbagai hal. Omong-omong, ada juga perintah yang sangat berguna untuk menghitung kata.
toilet -w, Anda juga dapat menggunakannya saat dibutuhkan.
Tambahan: Hal ini juga disebutkan dalam buku Panduan Bash-Scripting Tingkat Lanjut
mencatatperintah dan
faktorperintah, karena tidak tersedia di mesin, tidak ada tes.
faktorperintah dapat menghasilkan semua bilangan prima dari bilangan tertentu. menyukai:
$faktor 100100: 2 2 5 5
Pada titik ini, perhitungan numerik dari contoh pemrograman Shell berakhir. Artikel ini terutama memperkenalkan:
Operasi integer, operasi floating point, pembuatan angka acak, dan pembuatan urutan dalam pemrograman Shell
Perbedaan antara perintah bawaan Shell dan perintah eksternal, serta cara melihat jenis dan bantuannya
Beberapa cara untuk mengeksekusi skrip Shell
Beberapa perintah eksternal Shell yang umum digunakan:
sed,
awk,
memahami,
unik,
menyortirTunggu
Contoh: menambah angka; mencari pendapatan rata-rata bulanan;
AKU PAlamat; menghitung jumlah kata
Lainnya: Penggunaan terkait seperti daftar perintah, pengujian bersyarat, dll. telah dibahas dalam contoh di atas, harap baca dengan cermat.
Jika Anda punya waktu, silakan tinjau.
Panduan Pembuatan Skrip Bash Tingkat Lanjut
shell tiga belas pertanyaan
Dua belas artikel tentang dasar-dasar shell
panduan SED
Panduan Pengguna AWK
Beberapa forum diskusi Shell
LinuxSir.org
ChinaUnix.net
Saya membutuhkan waktu lebih dari 3 jam untuk menyelesaikan penulisan. Saat ini jam 23:33. Saatnya kembali ke asrama dan tidur. Saya akan memperbaiki kesalahan ketik dan menambahkan beberapa konten besok.
Pada tanggal 31 Oktober, beberapa kata diubah, contoh penghitungan pendapatan rata-rata bulanan rumah tangga ditambahkan, ringkasan dan referensi ditambahkan, dan semua kode ditambahkan.
Pemrograman shell adalah hal yang sangat menarik, jika Anda memikirkan: contoh penghitungan pendapatan rata-rata bulanan rumah tangga di atas, dan kemudian menggunakannya
M$ UnggulMembandingkan pekerjaan ini, Anda akan menemukan bahwa pekerjaan pertama sangat sederhana dan tidak merepotkan, serta memberi Anda perasaan mudah dalam menggunakannya.