$ i=0;$ ((i++))$ echo $i1$ let i++$ echo $i2$ expr $i + 13$ echo $i2$ echo $i 1 |
veranschaulichen:
Ausdrucknach
$i,
+, 1 durch Leerzeichen getrennt. Wenn eine Multiplikation durchgeführt wird, muss der Operator mit einem Escapezeichen versehen werden. Andernfalls interpretiert die Shell das Multiplikationszeichen als Platzhalterzeichen, was zu einem Syntaxfehler führt.
awkhinter
1 $Und
2 $jeweils verweisen
$iund 1, also die 1. und 2. Zahl von links nach rechts.
Verwenden Sie die integrierten Shell-Befehle, um die Typen der einzelnen Befehle wie folgt anzuzeigen:
$ Typ typetype ist eine in die Shell integrierte $ Typ letlet ist eine in die Shell integrierte $ Typ exprexpr ist gehasht (/usr/bin/expr)$ Typ bcbc ist gehasht (/usr/bin/bc)$ Typ awkawk ist /usr/bin/awk
Aus der obigen Demonstration geht hervor:
lassenEs ist ein integrierter Befehl von Shell, und die anderen sind allesamt externe Befehle
/usr/binVerzeichnis. Und
AusdruckUnd
v. ChrDa es gerade verwendet wurde, wurde es in den Speicher geladen.
HashTisch. Dies wird uns helfen, die Prinzipien hinter den verschiedenen Ausführungsmethoden von Skripten zu verstehen, die im vorherigen Kapitel vorgestellt wurden.
Hinweis: Wenn Sie Hilfe für verschiedene Befehle anzeigen möchten, z
lassenUnd
TypWährend Sie auf den integrierten Befehl der Shell warten, können Sie einen integrierten Befehl der Shell verwenden
helfenum zugehörige Hilfe anzuzeigen, und auf einige externe Befehle kann über einen externen Befehl von Shell zugegriffen werden
Mannum Hilfe, Verwendung wie z. B. anzuzeigen
helfen lassen,
manexprWarten.
#!/bin/bash# calc.shi=0;while [ $i -lt 10000 ]do ((i++)) doneeecho $i
Beschreibung: Hier vorbei
while [bedingter Ausdruck]; do .... fertigZyklus, um etwas zu erreichen.
-ltist kleiner als das Vorzeichen
<Weitere Informationen finden Sie unter
prüfenBefehlsverwendung:
Männertest.
Wie führe ich dieses Skript aus?
Methode 1: Übergeben Sie die Skriptdatei direkt als Parameter der Sub-Shell (Bash).
$ bash calc.sh$ Typ bashbash wird gehasht (/bin/bash)
Methode 2: Bestehen
bashintegrierte Befehle
.oder
Quelleimplementieren
$ ./calc.sh
oder
$ source ./calc.sh$ type .. ist eine integrierte Shell. $ type sourcesource ist eine integrierte Shell
Methode 3: Ändern Sie die Datei so, dass sie ausführbar ist, und führen Sie sie direkt unter der aktuellen Shell aus
$ chmod ./calc.sh $ ./calc.sh
Als nächstes demonstrieren wir nacheinander die Verwendung anderer Methoden zur Berechnung der Variablen plus eins, d. h.
((i++))Zeile mit einem der folgenden:
let i++;i=$(expr $i + 1)i=$(echo $i+1|bc)i=$(echo $i 1 | awk '{printf $1+$2;}')
Die Vergleichsberechnungszeit ist wie folgt:
$ Zeit calc.sh10000real 0m1.319suser 0m1.056ssys 0m0.036s$ Zeit calc_let.sh10000real 0m1.426suser 0m1.176ssys 0m0.032s$ Zeit calc_expr.sh1000real 0m27.425suser 0m5.060ssys 0m14.177s$ Zeit calc_bc.sh1000real 0m56.576suser 0m9.353ssys 0m24.618s$ Zeit ./calc_awk.sh100real 0m11.672suser 0m2.604ssys 0m2.660s
veranschaulichen:
ZeitDer Befehl kann verwendet werden, um die Ausführungszeit des Befehls zu zählen. Dieser Teil der Zeit umfasst die Gesamtlaufzeit, die Ausführungszeit des Benutzerbereichs und die Ausführungszeit des Kernelbereichs
ptraceImplementierung eines Systemaufrufs.
Durch den obigen Vergleich kann dies festgestellt werden
(())verfügt über die höchste betriebliche Effizienz. Und
lassenAls in die Shell integrierter Befehl ist er auch sehr effizient, aber
Ausdruck,
v. Chr,
awkDie Berechnungseffizienz ist relativ gering. Wenn die Shell selbst die entsprechende Arbeit erledigen kann, wird daher empfohlen, den von der Shell selbst bereitgestellten Funktionen Vorrang einzuräumen. Es gibt jedoch Funktionen, die die Shell selbst nicht ausführen kann, z. B. Gleitkommaoperationen. Daher ist die Hilfe externer Befehle erforderlich. Darüber hinaus sollten Sie angesichts der Portabilität von Shell-Skripten keine bestimmte Shell-spezifische Syntax verwenden, wenn die Leistung nicht entscheidend ist.
lassen,
Ausdruck,
v. Chrkann verwendet werden, um Modulo zu finden, und die Operatoren sind alle
%,Und
lassenUnd
v. ChrEs kann verwendet werden, um Potenzierungen zu finden
**, Letzteres ist
^. Zum Beispiel:
$ expr 5 % 21$ let i=5%2$ echo $i1$ echo 5 % 2 |
$ let i=5**2$ echo $i25$ ((i=5**2))$ echo $i25$ echo 5^2 |
Die Basiskonvertierung ist ebenfalls eine relativ häufige Operation, die Sie verwenden können
BashIntegrierte Unterstützung für
v. ChrUm beispielsweise die Oktalzahl 11 in eine Dezimalzahl umzuwandeln, können Sie Folgendes tun:
$ echo obase=10;ibase=8;11 |. bc -l9$ echo $((8#11))9
Die oben genannten wandeln alle Zahlen in einem bestimmten Basissystem in die Basis 10 um. Wenn Sie zwischen beliebigen Basissystemen konvertieren möchten, trotzdem
v. ChrFlexibler, da direkt einsetzbar
ibaseUnd
obaseGeben Sie die Basisquelle bzw. das Basiskonvertierungsziel an.
Wenn Sie einige Zeichenfolgen in einer bestimmten Basis ausdrücken möchten, können Sie diese verwenden
odBefehl, z. B. das Standardtrennzeichen
IFSeinschließlich Leerzeichen,
TABSie können auch Zeilenumbrüche verwenden
Mann ASCIIBeweis.
$ echo -n $IFS |. od -c0000000 t n0000003$ echo -n $IFS |
lassenUnd
AusdruckKeiner von beiden kann Gleitkommaoperationen ausführen, aber
v. ChrUnd
awkDürfen.
$ echo scale=3; 1/13 |. bc.076$ echo 1 13 |
veranschaulichen:
v. ChrBei der Ausführung von Gleitkommaoperationen muss die Genauigkeit angegeben werden, andernfalls ist sie standardmäßig 0, dh bei der Ausführung von Gleitkommaoperationen behält das Standardergebnis nur ganze Zahlen bei. Und
awkSehr flexibel bei der Steuerung der Anzahl der Dezimalstellen, einfach per
printfFormatkontrolle kann erreicht werden.
Nachtrag: In Gebrauch
v. ChrBei der Durchführung von Operationen, sofern nicht verwendet
SkalaGeben Sie die Präzision an
v. Chrdanach hinzufügen
-lMit dieser Option können auch Gleitkommaoperationen ausgeführt werden, die Standardgenauigkeit beträgt derzeit jedoch 20 Stellen. Zum Beispiel:
$ echo 1/13100 |. bc -l.00007633587786259541
verwenden
v. Chr. -lDie Berechnung kann eine hohe Genauigkeit erreichen:
$ export cos=0,996293; echo scale=100; a(sqrt(1-$cos^2)/$cos)*180/(a(1)*4) | -l4.9349547554113836327198340369318406051597063986552438753727649177325495504159766011527078286004072131
Natürlich kann es auch verwendet werden
awkZur Berechnung:
$ echo 0.996293 |. awk '{ printf(%sn, atan2(sqrt(1-$1^2),$1)*180/3.1415926535);}'4.93495
Hier wird zufällig ein Satz Testdaten generiert und der Dateiname lautet
Einkommen.txt.
1 3 44902 5 38963 4 31124 4 47165 4 45786 6 53997 3 50898 6 30299 4 619510 5 5145
Hinweis: Die drei Datenspalten oben sind Familienzahl, Familiengröße und monatliches Gesamteinkommen der Familie.
Analyse: Um die Familie mit dem höchsten durchschnittlichen Monatseinkommen zu finden, müssen Sie die folgenden zwei Spalten teilen, d. h. das durchschnittliche Monatseinkommen jeder Familie ermitteln und dann nach dem durchschnittlichen Monatseinkommen sortieren, um die Familie zu finden das höchste Einkommen.
erreichen:
#!/bin/bash# gettopfamily.sh[ $# -lt 1 ] && echo Bitte geben Sie die Einkommensdatei ein && Exit -1[ ! -f $1 ] && Echo $1 ist keine Datei && Exit -1income=$1awk '{ printf(%d %0.2fn, $1, $3/$2);}' $income |
veranschaulichen:
[ $# -lt 1 ]: Erfordert die Eingabe mindestens eines Parameters,
$#Ist die Anzahl der in der Shell übergebenen Parameter
[ ! -f $1 ]: Erfordert, dass der Eingabeparameter eine Datei ist.
-FZur Verwendung siehe
prüfenBefehl,
Männertest
Einkommen = 1 $: Weisen Sie der Einkommensvariablen die Eingabeparameter zu und verwenden Sie sie dann als
awkParameter, also die zu verarbeitenden Dateien
awk: Teilen Sie die dritte Spalte der Datei durch die zweite Spalte, um das durchschnittliche Monatseinkommen zu ermitteln. Unter Berücksichtigung der Genauigkeit werden zwei Ziffern der Genauigkeit beibehalten.
sortieren -k 2 -n -r:Hier ist das Ergebnis von
awkDie zweite Spalte des Ergebnisses
-k 2, das heißt, das durchschnittliche Monatseinkommen wird sortiert, sortiert nach Zahlen
-Nund in absteigender Reihenfolge sortiert
-R.
Demo:
$ ./gettopfamily.sh Einkommen.txt7 1696,339 1548,751 1496,674 1179,005 1144,5010 1029,006 899,832 779,203 778,008 504,83
Ergänzung: früher
Einkommen.txtDie Daten werden zufällig generiert. Bei manchen Experimenten ist es oft notwendig, einige Daten zufällig zu generieren. Im nächsten Abschnitt werden wir sie im Detail vorstellen. Hier wird generiert
Einkommen.txtDatenskript:
#!/bin/bash# genrandomdata.shfor i in $(seq 1 10)do echo $i $(($RANDOM/8192+3)) $((RANDOM/10+3000))done
Hinweis: Wird auch im obigen Skript verwendet
seqDer Befehl generiert eine Spalte mit Zahlen von 1 bis 10. Die detaillierte Verwendung dieses Befehls wird im letzten Abschnitt dieses Artikels näher erläutert.
Umgebungsvariablen
ZUFÄLLIGGenerieren Sie Zufallszahlen von 0 bis 32767, während
awkvon
Rand()Die Funktion kann Zufallszahlen zwischen 0 und 1 generieren.
$ echo $RANDOM81$ echo |. awk '{srand(); printf(%f, rand());}'0.237788
veranschaulichen:
srand()Wenn kein Parameter vorhanden ist, wird die aktuelle Zeit verwendet
Rand()Ein Zufallszahlengenerator
Samen.
kann passieren
ZUFÄLLIGskalierte Summe von Variablen
awkMitte
Rand()Verstärkung zu erreichen.
$ expr $RANDOM / 128$ echo |. awk '{srand(); printf(%dn, rand()*255);}'
Überlegung: Wenn Sie zufällig eine IP-Adresse für ein bestimmtes IP-Segment generieren möchten, wie sollten Sie das tun? Siehe Beispiel: Friendly erhält eine nutzbare IP-Adresse.
#!/bin/bash# getip.sh – automatisch eine nutzbare IP-Adresse erhalten# Autor: falcon <[email protected]># Update: Tue Oct 30 23:46:17 CST 2007# Legen Sie Ihr eigenes Netzwerk und Standard-Gateway fest , und die Zeitüberschreitung des Pings commandnet=192.168.1default_gateway=192.168.1.1over_time=2# überprüfen Sie die current ipaddressping -c 1 $default_gateway -W $over_time[ $? -eq 0 ] && echo the current ipaddress is okey && exit -1;while :; eth0 ifconfig eth0 $net.$(($RANDOM /130 +2)) up # Standard-Gateway-Route konfigurieren, Standard-GW hinzufügen $default_gateway # prüfen die neue Konfiguration ping -c 1 $default_gateway -W $over_time # if work, done [ $? -eq 0 ] && breakdone
Hinweis: Wenn Ihre Standard-Gateway-Adresse dies nicht ist
192.168.1.1, bitte konfigurieren Sie es selbst
default_gateway(kann verwendet werden
Route-nBefehl zum Anzeigen), weil mit
ifconfigWenn Sie die Adresse konfigurieren, können Sie sie nicht als Gateway-Adresse konfigurieren, da sonst Ihre IP-Adresse mit der des Gateways übereinstimmt und das gesamte Netzwerk nicht ordnungsgemäß funktioniert.
Tatsächlich kann eine Reihe von Zahlen durch eine Schleife generiert werden, aber warum nicht diese verwenden, wenn es verwandte Tools gibt?
seqEs ist ein so kleines Tool, das eine Reihe von Zahlen generieren kann. Sie können das aufsteigende Intervall der Zahlen oder das Trennzeichen zwischen zwei benachbarten Zahlen angeben.
$ 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
Eine typischere Verwendung
seqErstellen Sie beispielsweise einige Links in einem bestimmten Format und verwenden Sie sie dann
wgetLaden Sie diese herunter:
$ für i in `seq -fhttp://thns.tsinghua.edu.cn/thnsebooks/ebook73/%02g.pdf 1 21`;do wget -c $i; done
oder
$ für i in „seq -w 1 21“;do wget -c http://thns.tsinghua.edu.cn/thnsebooks/ebook73/$i;
Ergänzung: in
BashVersion 3 und höher, in
fürkreisförmig
InDahinter kann man direkt vorbeigehen
{1..5}Erzeugen Sie prägnanter Zahlen von 1 bis 5 (beachten Sie, dass zwischen 1 und 5 nur zwei Punkte stehen), zum Beispiel:
$ for i in {1..5}; do echo -n $i; done1 2 3 4 5
Lassen Sie uns zunächst eine Definition eines Wortes geben: eine einzelne oder mehrere aus Buchstaben bestehende Zeichenreihe.
Zählen Sie zunächst, wie oft jedes Wort vorkommt:
$ wget -c http://tinylab.org$ cat index.html |. sed -es/[^a-zA-Z]/n/g |
Zählen Sie dann die zehn am häufigsten vorkommenden Wörter:
$ wget -c http://tinylab.org$ cat index.html |. sed -es/[^a-zA-Z]/n/g | -k 1 -r |. head -10 524 a 238 tag 205 href 201 class 193 http 189 org 175 tinylab 174 www 146 div 128 Titel
veranschaulichen:
cat index.html: Gibt den Inhalt der Datei index.html aus
sed -es/[^a-zA-Z]/n/g: Ersetzen Sie nicht-alphabetische Zeichen durch Leerzeichen und behalten Sie nur alphabetische Zeichen bei
grep -v ^$: Leerzeilen entfernen
Sortieren: Sortieren
uniq -c: Zählen Sie die Anzahl der gleichen Zeilen, dh die Anzahl jedes Wortes
sortieren -n -k 1 -r: Laut der ersten Spalte
-k 1Nummer
-NUmgekehrte Reihenfolge
-RSortieren
Kopf -10: Nehmen Sie die ersten zehn Zeilen heraus
Zwei Ansätze kommen in Betracht:
Zählen Sie nur die Wörter, die gezählt werden müssen
Verwenden Sie den obigen Algorithmus, um die Anzahl aller Wörter zu zählen, und geben Sie dann die zu zählenden Wörter an den Benutzer zurück
Beide Methoden können jedoch durch die folgende Struktur implementiert werden. Schauen wir uns zunächst Methode eins an:
#!/bin/bash# statistic_words.shif [ $# -lt 1 ]; then echo Verwendung: Basisname $0 FILE WORDS .... exit -1fiFILE=$1((WORDS_NUM=$#-1))for n in $( seq $WORDS_NUM)do shift cat $FILE | ^$ |. sort |. grep ^$1$ |
veranschaulichen:
wenn Bedingungsteil: Erfordert mindestens zwei Parameter, die erste Wortdatei und die nachfolgenden Parameter sind die zu zählenden Wörter.
DATEI=$1: Ruft den Dateinamen ab, der die erste Zeichenfolge nach dem Skript ist
((WORDS_NUM=$#-1)): Ermitteln Sie die Anzahl der Wörter, dh die Gesamtzahl der Parameter
$#abzüglich des Dateinamenparameters (1)
für Schleifenteil: Zuerst passieren
seqErzeugen Sie eine Wortnummernreihe, die gezählt werden muss.
Schichtist eine in Shell integrierte Variable (bitte übergeben).
Hilfe bei der UmstellungHolen Sie sich Hilfe) verschiebt die vom Benutzer über die Befehlszeile eingegebenen Parameter der Reihe nach rückwärts und verwendet den aktuellen Parameter als ersten Parameter.
1 $, ist so passiert
1 $Sie können alle vom Benutzer eingegebenen Wörter durchlaufen (wenn Sie sorgfältig darüber nachdenken, scheint es ein Array-Index zu sein). Sie können darüber nachdenken
SchichtErsetzen Sie den nächsten Satz durch
echo $1prüfen
SchichtVerwendung
Demo:
$ chmod +x statistic_words.sh$ ./statistic_words.sh index.html tinylab linux python 175 tinylab 43 linux 3 python
Schauen wir uns Methode zwei an, wir müssen sie nur ändern
SchichtDer nächste Satz reicht:
#!/bin/bash# statistic_words.shif [ $# -lt 1 ]; then echo FEHLER: Sie sollten mindestens 2 Wörter eingeben; echo Verwendung: Basisname $0 FILE WORDS .... exit -1fiFILE=$1((WORDS_NUM= $#-1))für n in $(seq $WORDS_NUM)verschieben Sie cat $FILE | -es/[^a-zA-Z]/n/g |. grep -v ^$ |
Demo:
$ ./statistic_words.sh index.html tinylab linux python 175 tinylab 43 linux 3 python
Erläuterung: Offensichtlich ist Methode eins viel effizienter, da sie die Wörter, die gezählt werden müssen, im Voraus findet und sie dann zählt, während letzteres nicht der Fall ist. In der Tat, wenn Sie verwenden
grepvon
-EOption müssen wir keine Schleife einführen, sondern können dies mit einem Befehl tun:
$ cat index.html |. sed -es/[^a-zA-Z]/n/g |. grep -v ^$ |
oder
$ cat index.html |. sed -es/[^a-zA-Z]/n/g |. grep -v ^$ |^linux$ |
Beschreibung: Muss beachtet werden
sedBefehle können Dateien direkt verarbeiten, ohne sie zu übergeben
KatzeDie Befehlsausgabe wird dann durch die Pipeline geleitet, wodurch unnötige Pipeline-Vorgänge reduziert werden können, sodass der obige Befehl wie folgt vereinfacht werden kann:
$ sed -es/[^a-zA-Z]/n/g index.html |. grep -v ^$ |. sort |
Es ist also ersichtlich, dass diese Befehle
sed,
grep,
einzigartig,
SortierenWie nützlich sie sind, obwohl sie allein nur einfache Funktionen erfüllen, können sie durch bestimmte Kombinationen eine Vielzahl von Dingen erreichen. Übrigens gibt es auch einen sehr nützlichen Befehl zum Zählen von Wörtern.
wc -wSie können es auch bei Bedarf verwenden.
Ergänzung: Es wird auch im Buch „Advanced Bash-Scripting Guide“ erwähnt
JotBefehl und
FaktorDa dieser Befehl auf der Maschine nicht verfügbar ist, gibt es keinen Test.
FaktorDer Befehl kann alle Primzahlen einer bestimmten Zahl generieren. wie:
$-Faktor 100100: 2 2 5 5
An diesem Punkt endet die numerische Berechnung des Shell-Programmierbeispiels. In diesem Artikel wird hauptsächlich Folgendes vorgestellt:
Ganzzahloperationen, Gleitkommaoperationen, Zufallszahlengenerierung und Sequenzgenerierung in der Shell-Programmierung
Der Unterschied zwischen den integrierten Shell-Befehlen und den externen Befehlen sowie die Anzeige ihrer Typen und Hilfe
Mehrere Möglichkeiten, Shell-Skripte auszuführen
Mehrere häufig verwendete externe Shell-Befehle:
sed,
awk,
grep,
einzigartig,
SortierenWarten
Beispiel: Erhöhung der Zahlen; Ermittlung des durchschnittlichen Monatseinkommens;
IPAdresse; zählen Sie die Anzahl der Wörter
Sonstiges: Verwandte Verwendungen wie Befehlslisten, bedingte Tests usw. wurden in den obigen Beispielen behandelt. Bitte lesen Sie sie sorgfältig durch.
Wenn Sie Zeit haben, lesen Sie es bitte durch.
Erweitertes Bash-Scripting-Handbuch
Shell dreizehn Fragen
Zwölf Artikel zu Shell-Grundlagen
SED-Handbuch
AWK-Benutzerhandbuch
Mehrere Shell-Diskussionsforen
LinuxSir.org
ChinaUnix.net
Es hat mehr als 3 Stunden gedauert, bis ich mit dem Schreiben fertig bin. Es ist Zeit, zurück in den Schlafsaal zu gehen und morgen etwas zu schreiben.
Am 31. Oktober wurden einige Formulierungen geändert, ein Beispiel zur Berechnung des durchschnittlichen monatlichen Haushaltseinkommens hinzugefügt, eine Zusammenfassung und Referenzen hinzugefügt und alle Codes angehängt.
Shell-Programmierung ist eine sehr interessante Sache, wenn Sie darüber nachdenken: Das obige Beispiel berechnet das durchschnittliche monatliche Haushaltseinkommen und verwendet es dann
M$ ExcelWenn Sie diese Arbeit vergleichen, werden Sie feststellen, dass Ersteres so einfach und problemlos ist und Ihnen ein Gefühl der Benutzerfreundlichkeit vermittelt.