$ i=0;$ ((i++))$ echo $i1$ let i++$ echo $i2$ expr $i + 13$ echo $i2$ echo $i 1 | awk '{printf $1+$2}'3
例証します:
式後
$i、
+, 1はスペースで区切ります。乗算を実行する場合、演算子をエスケープする必要があります。エスケープしないと、シェルは乗算記号をワイルドカード文字として解釈し、構文エラーが発生します。
ああ後ろに
1ドルそして
2ドルそれぞれ参照
$i1、つまり左から右に 1 番目と 2 番目の数字です。
シェルの組み込みコマンドを使用して、次のように各コマンドのタイプを表示します。
$ type typetype はシェル組み込みです$ type letlet はシェル組み込みです$ type exprexpr はハッシュ化されます (/usr/bin/expr)$ type bcbc はハッシュ化されます (/usr/bin/bc)$ type awkawk は /usr/bin/awk
それは上記のデモからわかります。
させてこれはシェルの組み込みコマンドであり、他のいくつかは外部コマンドであり、すべて
/usr/binディレクトリ。そして
式そして
紀元前使用したばかりなのでメモリに読み込まれています。
ハッシュテーブル。これは、前の章で紹介したスクリプトのさまざまな実行方法の背後にある原則を理解するのに役立ちます。
注: さまざまなコマンドのヘルプを表示したい場合は、
させてそして
タイプシェルの組み込みコマンドを待っているので、シェルの組み込みコマンドを使用できます
ヘルプ関連するヘルプを表示し、一部の外部コマンドにはシェルの外部コマンドを介してアクセスできます。
男ヘルプや使用方法などを表示するには
助けてみましょう、
操作待って。
#!/bin/bash# calc.shi=0;while [ $i -lt 10000 ]do ((i++)) doneecho $i
説明: ここを通過します
while [条件式]; do .... 完了達成するためのサイクル。
-ltは符号未満です
<、詳細についてはを参照してください
テストコマンドの使用法:
男のテスト。
このスクリプトを実行するにはどうすればよいでしょうか?
方法 1: スクリプト ファイルをサブシェルのパラメータとして直接渡す (Bash)
$ bash calc.sh$ タイプ bashbash はハッシュ化されます (/bin/bash)
方法 2: パス
バッシュ組み込みコマンド
。または
ソース埋め込む
$ ./calc.sh
または
$source ./calc.sh$ type .. はシェル組み込み$タイプですsourcesourceはシェル組み込みです
方法 3: ファイルを実行可能に変更し、現在のシェルで直接実行する
$ chmod ./calc.sh $ ./calc.sh
次に、他のメソッドを使用して変数に 1 を加えた値を計算する方法を 1 つずつ示します。
((i++))次のいずれかの行を入力します。
let i++;i=$(expr $i + 1)i=$(echo $i+1|bc)i=$(echo $i 1 | awk '{printf $1+$2;}')
比較計算時間は以下の通りです。
$ time calc.sh10000real 0m1.319suser 0m1.056ssys 0m0.036s$ time calc_let.sh10000real 0m1.426suser 0m1.176ssys 0m0.032s$ time calc_expr.sh1000real 0m27.425suser 0m5.060ssys 0m14.177s$ 時間 calc_bc.sh1000real 0m56.576suser 0m9.353ssys 0m24.618s$ time ./calc_awk.sh100real 0m11.672suser 0m2.604ssys 0m2.660s
例証します:
時間このコマンドを使用して、コマンドの実行時間をカウントできます。この部分には、合計実行時間、ユーザー空間実行時間、およびカーネル空間実行時間が含まれます。
ptraceシステムコールの実装。
上記の比較から、次のことがわかります。
(())最も高い業務効率を実現します。そして
させてシェル組み込みコマンドとしても非常に効率的ですが、
式、
紀元前、
ああ計算効率は比較的低いです。したがって、シェル自体で関連する作業を完了できる場合は、シェル自体が提供する機能を優先することをお勧めします。ただし、浮動小数点演算など、シェル自体では完了できない機能もあるため、外部コマンドの助けが必要です。さらに、シェル スクリプトの移植性を考慮して、パフォーマンスが重要でない場合は、特定のシェル固有の構文を使用しないでください。
させて、
式、
紀元前モジュロを見つけるために使用でき、演算子はすべて
%、そして
させてそして
紀元前累乗を求めるために使用できます。前者は異なります。
**、後者は
^。例えば:
$ expr 5 % 21$ let i=5%2$ echo $i1$ echo 5 % bc1$ ((i=5%2))$ echo $i1 |
$ let i=5**2$ echo $i25$ ((i=5**2))$ echo $i25$ echo 5^2 |
基底変換も比較的一般的な操作です。
バッシュ組み込みのサポート
紀元前たとえば、8 進数の 11 を 10 進数に変換するには、次のようにします。
$ echo obase=10;ibase=8;11 | bc -l9$ echo $((8#11))9
上記はすべて、特定の基数系の数値を 10 進数に変換します。任意の基数系間で変換したい場合でも、
紀元前直接使用できるため、より柔軟です
ibaseそして
おばせベースソースとベース変換ターゲットをそれぞれ指定します。
特定のベースでいくつかの文字列を表現したい場合は、次のように使用できます。
ODコマンド (デフォルトの区切り文字など)
IFSスペースも含めて、
タブ改行と同様に、次のように使用できます。
アスキー男証拠。
$ echo -n $IFS od -c0000000 t n0000003$ echo -n $IFS od -b0000000 040 011 0120000003
させてそして
式どちらも浮動小数点演算は実行できませんが、
紀元前そして
ああできる。
$ エコー スケール = 3 | bc.076$ エコー 1 13 | awk '{printf(%0.3fn,$1/$2)}'0.077
例証します:
紀元前浮動小数点演算を実行する場合は精度を指定する必要があります。指定しない場合はデフォルトで 0 になります。つまり、浮動小数点演算を実行する場合、デフォルトの結果は整数のみを保持します。そして
ああ小数点以下の桁数を非常に柔軟に制御できます。
プリントフフォーマット制御が実現できます。
補足:使用中
紀元前操作を行うとき、使用しない場合
規模での精度を指定します
紀元前後に追加
-lオプションを使用すると、浮動小数点演算も実行できますが、このときのデフォルトの精度は 20 桁です。例えば:
$ エコー 1/13100 bc -l.00007633587786259541
使用
bc -l計算により高い精度を実現できます。
$ エクスポート cos=0.996293; エコー スケール = 100; a(sqrt(1-$cos^2)/$cos)*180/(a(1)*4) -l4.9349547554113836327198340369318406051597063986552438753727649177325495504159766011527078286004072131
もちろんそれも使えます
ああ計算するには:
$ echo 0.996293 | awk '{ printf(%sn, atan2(sqrt(1-$1^2),$1)*180/3.1415926535);}'4.93495
ここではテスト データのセットがランダムに生成され、ファイル名は
収入.txt。
1 3 44902 5 38963 4 31124 4 47165 4 45786 6 53997 3 50898 6 30299 4 619510 5 5145
注: 上記の 3 つのデータ列は、家族数、家族人数、および家族の月収合計です。
分析: 平均月収が最も高い家族を見つけるには、次の 2 つの列を分割する必要があります。つまり、各家族の平均月収を見つけ、平均月収に従って並べ替えて、次の 2 つの列を見つける必要があります。最高の収入。
成し遂げる:
#!/bin/bash# gettopfamily.sh[ $# -lt 1 ] && echo 収入ファイルを入力してください && exit -1[ ! -f $1 ] && echo $1 はファイルではありません && exit -1income=$1awk '{ printf(%d %0.2fn, $1, $3/$2);}' $income sort -k 2 -n -r
例証します:
[ $# -lt 1 ]: 少なくとも 1 つのパラメータを入力する必要があります。
$#シェルに渡されるパラメータの数です
[ ! -f $1 ]: 入力パラメータはファイルである必要があります。
-f使用方法については、を参照してください。
テスト注文、
男のテスト
収入=1ドル: 入力パラメータを収入変数に割り当て、それを次のように使用します。
ああパラメータ、つまり処理されるファイル
ああ: ファイルの 3 番目の列を 2 番目の列で除算して、精度を考慮して 2 桁の精度を維持します。
ソート -k 2 -n -r:結果は次のとおりです
ああ結果の 2 列目
-k2つまり、平均月収が数値で並べ替えられます。
-n、降順に並べ替えます
-r。
デモ:
$ ./gettopfamily.sh 収入.txt7 1696.339 1548.751 1496.674 1179.005 1144.5010 1029.006 899.832 779.203 778.008 504.83
補足:前回
収入.txtデータはランダムに生成されます。実験を行う際には、データをランダムに生成する必要があることがよくあります。次のセクションで詳しく説明します。ここで生成されます
収入.txtデータスクリプト:
#!/bin/bash# genrandomdata.shfor i in $(seq 1 10)do echo $i $(($RANDOM/8192+3)) $((RANDOM/10+3000))done
注: 上記のスクリプトでも使用されます
連続このコマンドは、1 から 10 までの数字の列を生成します。このコマンドの詳細な使用法については、この記事の最後のセクションでさらに紹介します。
環境変数
ランダム0 ~ 32767 の乱数を生成します。
ああの
ランド()この関数は 0 から 1 までの乱数を生成できます。
$ echo $RANDOM81$ echo | awk '{srand();}'0.237788
例証します:
スランド()パラメータがない場合は、現在時刻が使用されます。
ランド()乱数発生器
シード。
通過できる
ランダム変数のスケーリングされた合計
ああ真ん中
ランド()増幅を達成するために。
$ expr $RANDOM / 128$ echo | awk '{srand(); printf(%dn, rand()*255);}'
考えてみます: 特定の IP セグメントの IP アドレスをランダムに生成したい場合、どうすればよいでしょうか?例を参照してください: 使用可能な IP アドレスをフレンドリに取得します。
#!/bin/bash# getip.sh -- 使用可能な IP アドレスを自動的に取得します# 著者: falcon <[email protected]># 更新: 火 10 月 30 日 23:46:17 CST 2007# 独自のネットワーク、デフォルト ゲートウェイを設定します、ping のタイムアウト commandnet=192.168.1default_gateway=192.168.1.1over_time=2# を確認してください。 current ipaddressping -c 1 $default_gateway -W $over_time[ $? -eq 0 ] && echo the current ipaddress is ok! && exit -1;while do # 現在の設定をクリア ifconfig eth0 down # の IP アドレスを設定しますeth0 ifconfig eth0 $net.$(($RANDOM /130 +2)) up # デフォルトゲートウェイのルートを設定します add default gw $default_gateway # check新しい設定 ping -c 1 $default_gateway -W $over_time # うまくいったら終了 [ $? -eq 0 ] && ブレークダン
注: デフォルト ゲートウェイ アドレスが異なる場合は、
192.168.1.1、自分で設定してください
デフォルトゲートウェイ(使用できます
ルートn表示するコマンド)、使用しているため
ifconfigアドレスを構成するときに、そのアドレスをゲートウェイ アドレスとして構成することはできません。そうしないと、IP アドレスがゲートウェイと同じになり、ネットワーク全体が正しく動作しなくなります。
実際にはループを通じて一連の数値を生成することができますが、関連するツールがある場合はそれを使用してみてはいかがでしょうか。
連続これは、一連の数値を生成できる小さなツールです。数値の増加間隔を指定したり、隣接する 2 つの数値の間の区切り文字を指定したりできます。
$ 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
より一般的な使用法
連続たとえば、特定の形式でいくつかのリンクを構築し、次を使用します。
ウィゲットこれらをダウンロードしてください:
$ for i in `seq -fhttp://thns.tsinghua.edu.cn/thnsebooks/ebook73/%02g.pdf 1 21`;do wget -c $i 完了;
または
$ for i in `seq -w 1 21`;do wget -c http://thns.tsinghua.edu.cn/thnsebooks/ebook73/$i 完了;
補足:
バッシュバージョン 3 以降では、
のために円形
で後ろなら直接追い越せます
{1..5}より簡潔に 1 から 5 までの数値を生成します (1 と 5 の間にはドットが 2 つしかないことに注意してください)。次に例を示します。
$ for i in {1..5}; do echo -n $i 完了1 2 3 4 5
まず単語の定義を示します。文字で構成される単一または複数の文字列です。
まず、各単語の出現数を数えます。
$ wget -c http://tinylab.org$ catindex.html sed -es/[^a-zA-Z]/n/g | uniq -c |
次に、最も頻繁に出現する単語の上位 10 個を数えます。
$ wget -c http://tinylab.org$ sed -es/[^a-zA-Z]/n/g | uniq -c | -k 1 -r ヘッド -10 524 a 238 タグ 205 href 201 クラス 193 http 189 org 175 tinylab 174 www 146 div 128タイトル
例証します:
猫のインデックス.html:index.htmlファイルの内容を出力します。
sed -es/[^a-zA-Z]/n/g: 英字以外の文字をスペースに置き換え、英字のみを保持します。
grep -v ^$: 空白行を削除します
選別: 選別
ユニーク -c:同じ行の数、つまり各単語の数を数えます。
ソート -n -k 1 -r: 最初のコラムによると
-k1番号
-n逆順
-r選別
頭 -10: 最初の10行を取り出します
次の 2 つのアプローチが考えられます。
数える必要がある単語だけを数えます
上記のアルゴリズムを使用してすべての単語の数をカウントし、カウントする必要がある単語をユーザーに返します。
ただし、両方の方法は次の構造を通じて実装できます。まず方法 1 を見てみましょう。
#!/bin/bash# statistic_words.shif [ $# -lt 1 ]; その後 echo 使用法:basename $0 FILE WORDS .... exit -1fiFILE=$1((WORDS_NUM=$#-1))for n in $( seq $WORDS_NUM)do シフト cat $FILE sed -es/[^a-zA-Z]/n/g | ^$ | ソート ^$1$ |
例証します:
if 条件部分: 少なくとも 2 つのパラメータが必要です。最初の単語ファイルと後続のパラメータはカウントされる単語です。
ファイル=$1: スクリプトの後の最初の文字列であるファイル名を取得します。
((WORDS_NUM=$#-1)): 単語数、つまりパラメータの総数を取得します。
$#ファイル名パラメータを引いたもの (1)
ループ部分用: 最初にパスします
連続カウントする必要がある単語数シリーズを生成します。
シフトシェルの組み込み変数です (渡してください)
シフトを手伝ってくださいヘルプを参照)、ユーザーがコマンド ラインから渡したパラメーターを順番に後方に移動し、現在のパラメーターを最初のパラメーターとして使用します。
1ドル、このように通過しました
1ドルユーザーが入力したすべての単語をたどることができます (よく考えると、これは配列の添字のように思えます)。検討していただけます
シフト次の文を次のように置き換えます
エコー $1テスト
シフト使用法
デモ:
$ chmod +x statistic_words.sh$ ./statistic_words.shindex.html tinylab linux python 175 tinylab 43 linux 3 python
方法 2 を見てみましょう。変更する必要があるのは、
シフト次の文だけで十分です。
#!/bin/bash# statistic_words.shif [ $# -lt 1 ]; 次に echo エラー: 少なくとも 2 つの単語を入力する必要があります; echo 使用法: Basename $0 FILE WORDS .... exit -1fiFILE=$1((WORDS_NUM= $#-1))$(seq $WORDS_NUM) の n については、cat $FILE をシフトします | -es/[^a-zA-Z]/n/g grep -c grep $1$done |
デモ:
$ ./statistic_words.shindex.html tinylab linux python 175 tinylab 43 linux 3 python
説明: 明らかに、方法 1 は、カウントする必要がある単語を事前に見つけてからカウントするため、はるかに効率的ですが、後者は当てはまりません。実際に使用すると、
grepの
-Eオプションを使用すると、ループを導入する必要はありませんが、1 つのコマンドで実行できます。
$ catindex.html | sed -es/[^a-zA-Z]/n/g | grep -v ^$ ソート | ^tinylab$|^linux$ |
または
$ catindex.html | sed -es/[^a-zA-Z]/n/g | grep -v ^$ ソート | Linux 175
説明: 注意が必要です
セドコマンドはファイルを渡さずに直接処理できます
猫コマンド出力はパイプラインを介して渡されるため、不必要なパイプライン操作が削減されるため、上記のコマンドは次のように簡略化できます。
$ sed -es/[^a-zA-Z]/n/g インデックス.html | grep -v ^$ ソート | uniq -c 43 linux 175 tinylab
したがって、これらのコマンドは
セド、
grep、
ユニークな、
選別単体では単純な機能しか実行できませんが、組み合わせによってさまざまな機能を実現できます。ちなみに、単語を数える非常に便利なコマンドもあります。
トイレ -w、必要に応じて使用することもできます。
補足: 『Advanced Bash-Scripting Guide』にも記載されています
冗談コマンドと
要素コマンドはマシンでは使用できないため、テストはありません。
要素コマンドは、特定の数のすべての素数を生成できます。のように:
$ 因数 100100: 2 2 5 5
この時点で、シェル プログラミング例の数値計算は終了します。この記事では主に以下の内容を紹介します。
シェルプログラミングにおける整数演算、浮動小数点演算、乱数生成、シーケンス生成
シェルの組み込みコマンドと外部コマンドの違い、およびその種類とヘルプの表示方法
シェルスクリプトを実行するいくつかの方法
よく使用されるいくつかのシェル外部コマンド:
セド、
ああ、
grep、
ユニークな、
選別待って
例: 数値の増加、平均月収の自動取得。
IP住所; 単語数を数える
その他: コマンド リスト、条件テストなどの関連する使用法については、上記の例で説明されています。よく読んでください。
お時間がありましたら、ぜひご検討ください。
高度な Bash スクリプト ガイド
シェル13の質問
シェルの基本に関する 12 の記事
SEDマニュアル
AWK ユーザーマニュアル
いくつかのシェル ディスカッション フォーラム
LinuxSir.org
ChinaUnix.net
書き終えるのに 3 時間以上かかりました。現在 23 時 33 分です。明日は誤字を修正し、内容を追加します。
10月31日、文言の一部を修正し、平均世帯月収の計算例を追加、概要と参考文献を追加、全コードを追記しました。
シェル プログラミングは、次のことを考えると非常に興味深いものです。平均世帯月収を計算する上記の例を使用して、
M$エクセルこの作業を比較すると、前者の方が非常にシンプルで手間がかからず、使いやすさを感じられることがわかります。