$ i=0;$ ((i++))$ echo $i1$ deixe i++$ echo $i2$ expr $i + 13$ echo $i2$ echo $i 1 |
ilustrar:
expressãodepois
$eu,
+, 1 separados por espaços. Se a multiplicação for realizada, o operador precisa ter escape, caso contrário o Shell interpretará o sinal de multiplicação como um caractere curinga, resultando em um erro de sintaxe;
estranhoatrás
US$ 1e
US$ 2referem-se respectivamente a
$eue 1, ou seja, o 1º e o 2º números da esquerda para a direita.
Use os comandos integrados do Shell para visualizar os tipos de cada comando da seguinte maneira:
$ tipo typetype é um shell embutido$ tipo letlet é um shell embutido$ tipo expreexpr é hash (/usr/bin/expr)$ tipo bcbc é hash (/usr/bin/bc)$ tipo awkawk é /usr/bin/awk
Isso pode ser visto na demonstração acima:
deixarÉ um comando interno do Shell, e os outros são comandos externos, todos em
/usr/bindiretório. e
expressãoe
a.C.Por ter acabado de ser usado, foi carregado na memória.
hashmesa. Isso nos ajudará a compreender os princípios por trás dos vários métodos de execução de scripts apresentados no capítulo anterior.
Nota: Se você quiser ver a ajuda de comandos diferentes, por
deixare
tipoAguardando o comando interno do Shell, você pode usar um comando interno do Shell
ajudapara visualizar a ajuda relacionada, e alguns comandos externos podem ser acessados através de um comando externo do Shell
homempara visualizar ajuda, uso como
ajude, deixe,
manexprespere.
#!/bin/bash# calc.shi=0;while [ $i -lt 10000 ]do ((i++)) doneeecho $i
Descrição: Passe aqui
enquanto [expressão condicional]; faça .... concluídoCiclo para alcançar.
-lté menor que sinal
<, veja para detalhes
testeUso do comando:
teste de homem.
Como executar este script?
Método 1: passe diretamente o arquivo de script como parâmetro do sub-Shell (Bash)
$ bash calc.sh $ tipo bashbash é hash (/bin/bash)
Método 2: passar
festacomandos integrados
.ou
fonteimplementar
$ ./calc.sh
ou
$ source ./calc.sh$ type .. é um shell embutido$ type sourcesource é um shell embutido
Método 3: Modifique o arquivo para ser executável e execute-o diretamente no Shell atual
$chmod./calc.sh $./calc.sh
A seguir, demonstraremos um por um a utilização de outros métodos para calcular a variável mais um, ou seja,
((eu++))linha com um dos seguintes:
deixe i++;i=$(expr $i + 1)i=$(echo $i+1|bc)i=$(echo $i 1 | awk '{printf $1+$2;}')
O tempo de cálculo de comparação é o seguinte:
$ tempo calc.sh10000real 0m1.319suser 0m1.056ssys 0m0.036s$ tempo calc_let.sh10000real 0m1.426suser 0m1.176ssys 0m0.032s$ tempo calc_expr.sh1000real 0m27.425suser 0m5.060ssys 0m14.177s$ tempo calc_bc.sh1000real 0m56.576suser 0m9.353ssys 0m24.618s$ tempo ./calc_awk.sh100real 0m11.672suser 0m2.604ssys 0m2.660s
ilustrar:
tempoO comando pode ser usado para contar o tempo de execução do comando. Esta parte do tempo inclui o tempo total de execução, o tempo de execução do espaço do usuário e o tempo de execução do espaço do kernel.
rastreamentoImplementação de chamada de sistema.
Através da comparação acima, pode-se descobrir que
(())tem a maior eficiência operacional. e
deixarComo um comando interno do Shell, também é muito eficiente, mas
expressão,
a.C.,
estranhoA eficiência do cálculo é relativamente baixa. Portanto, se o próprio Shell puder realizar o trabalho relevante, recomenda-se dar prioridade às funções fornecidas pelo próprio Shell. Mas existem funções que o próprio Shell não consegue completar, como operações de ponto flutuante, por isso é necessária a ajuda de comandos externos. Além disso, considerando a portabilidade dos scripts Shell, não use determinada sintaxe específica do Shell quando o desempenho não for crítico.
deixar,
expressão,
a.C.pode ser usado para encontrar o módulo, e os operadores são todos
%,e
deixare
a.C.Pode ser usado para encontrar a exponenciação. Os operadores são diferentes.
**, este último é
^. Por exemplo:
$ expr 5% 21$ deixe i=5%2$ echo $i1$ echo 5% bc1$ ((i=5%2))$ echo $i1
$ deixe i=5**2$ echo $i25$ ((i=5**2))$ echo $i25$ echo 5^2 |
A conversão de base também é uma operação relativamente comum que você pode usar.
BashSuporte integrado para
a.C.Para completar, por exemplo, converter 11 de octal para decimal, você pode:
$ echo obase=10;ibase=8;11 | bc -l9$ echo $((8#11))9
Acima de tudo, converte números em um determinado sistema básico em base 10. Se você deseja converter entre qualquer sistema básico, ainda
a.C.Mais flexível porque pode ser usado diretamente
ibasee
obaseEspecifique a origem base e o destino de conversão base, respectivamente.
Se você quiser expressar algumas strings em uma base específica, você pode usar
ahcomando, como o separador padrão
SEincluindo espaços,
ABAAlém de quebras de linha, você pode usar
homem asciievidência.
$ echo -n $IFS | od -c0000000 t n0000003$ echo -n $IFS |
deixare
expressãoNenhum deles pode realizar operações de ponto flutuante, mas
a.C.e
estranhoPode.
$ escala de eco = 3; 1/13 | bc.076 $ echo 1 13 |
ilustrar:
a.C.A precisão precisa ser especificada ao realizar operações de ponto flutuante, caso contrário o padrão é 0, ou seja, ao realizar operações de ponto flutuante, o resultado padrão retém apenas números inteiros. e
estranhoMuito flexível no controle do número de casas decimais, bastando
imprimirO controle de formato pode ser alcançado.
Suplemento: Em uso
a.C.Ao realizar operações, se não for usado
escalaEspecifique a precisão enquanto estiver em
a.C.adicionar depois
-euopção, operações de ponto flutuante também podem ser executadas, mas a precisão padrão neste momento é de 20 dígitos. Por exemplo:
$ eco 1/13100 | bc -l.00007633587786259541
usar
bc -lO cálculo pode atingir alta precisão:
$ exportar cos=0,996293; escala de eco=100; a(sqrt(1-$cos^2)/$cos)*180/(a(1)*4) | -l4.9349547554113836327198340369318406051597063986552438753727649177325495504159766011527078286004072131
Claro que também pode ser usado
estranhoPara calcular:
$ echo 0,996293 |
Um conjunto de dados de teste é gerado aleatoriamente aqui e o nome do arquivo é
renda.txt.
1 3 44902 5 38963 4 31124 4 47165 4 45786 6 53997 3 50898 6 30299 4 619510 5 5145
Nota: As três colunas de dados acima são número da família, tamanho da família e renda familiar mensal total.
Análise: Para encontrar a família com maior renda média mensal, é necessário dividir as duas colunas a seguir, ou seja, encontrar a renda média mensal de cada família, e depois ordenar de acordo com a renda média mensal para encontrar a família com a maior renda.
concluir:
#!/bin/bash# gettopfamily.sh[ $# -lt 1 ] && echo insira o arquivo de renda && exit -1[ ! printf(%d %0.2fn, $1, $3/$2);}' $renda | ordenar -k 2 -n -r
ilustrar:
[ $# -lt1 ]: Requer que pelo menos um parâmetro seja inserido,
$#É o número de parâmetros passados no Shell
[!-f$1]: Requer que o parâmetro de entrada seja um arquivo,
-fPara uso, consulte
testeOrdem,
teste de homem
renda = $ 1: Atribua os parâmetros de entrada à variável de renda e, em seguida, use-os como
estranhoparâmetros, ou seja, os arquivos a serem processados
estranho: Divida a terceira coluna do arquivo pela segunda coluna para encontrar a renda média mensal Levando em consideração a precisão, são mantidos dois dígitos de precisão.
classificar -k 2 -n -r:Aqui está o resultado de
estranhoA segunda coluna do resultado
-k 2, ou seja, a renda média mensal é ordenada, ordenada por números
-ne classificados em ordem decrescente
-r.
Demonstração:
$ ./gettopfamily.sh renda.txt7 1696,339 1548,751 1496,674 1179,005 1144,5010 1029,006 899,832 779,203 778,008 504,83
Suplemento: anterior
renda.txtOs dados são gerados aleatoriamente. Ao fazer alguns experimentos, muitas vezes é necessário gerar alguns dados aleatoriamente. Na próxima seção, iremos apresentá-los em detalhes. Aqui é gerado
renda.txtRoteiro de dados:
#!/bin/bash# genrandomdata.shfor i in $(seq 1 10)do echo $i $(($RANDOM/8192+3)) $((RANDOM/10+3000))feito
Nota: Também usado no script acima
sequênciaO comando gera uma coluna de números de 1 a 10. O uso detalhado deste comando será apresentado na última seção deste artigo.
variáveis de ambiente
ALEATÓRIOGere números aleatórios de 0 a 32767, enquanto
estranhode
Rand()A função pode gerar números aleatórios entre 0 e 1.
$ echo $RANDOM81$ echo |'{srand();
ilustrar:
srand()Quando não há parâmetro, a hora atual é usada como
Rand()Um gerador de números aleatórios
semente.
pode passar
ALEATÓRIOsoma escalonada de variáveis
estranhomeio
Rand()para obter amplificação.
$ expr $RANDOM / 128$ echo |
Pensando: se você deseja gerar aleatoriamente um endereço IP para um determinado segmento de IP, como deve fazê-lo? Veja o exemplo: Amigável para obter um endereço IP utilizável.
#!/bin/bash# getip.sh - obtenha um endereço IP utilizável automaticamente# autor: falcon <[email protected]># atualização: terça-feira, 30 de outubro 23:46:17 CST 2007# defina sua própria rede, gateway padrão , e o tempo limite de ping commandnet=192.168.1default_gateway=192.168.1.1over_time=2# verifique o current ipaddressping -c 1 $default_gateway -W $over_time[ $? -eq 0 ] && echo o endereço IP atual está ok! eth0 ifconfig eth0 $net.$(($RANDOM /130 +2)) up # configura a rota do gateway padrão add default gw $default_gateway # verifica a nova configuração ping -c 1 $default_gateway -W $over_time # se funcionar, termine [ $? -eq 0 ] && breakdone
Nota: Se o seu endereço de gateway padrão não for
192.168.1.1, configure você mesmo
gateway_padrão(pode ser usado
rota-ncomando para visualizar), porque usando
ifconfigAo configurar o endereço, você não pode configurá-lo como endereço do gateway, caso contrário seu endereço IP será igual ao do gateway, fazendo com que toda a rede não funcione corretamente.
Na verdade, uma série de números pode ser gerada através de um loop, mas por que não usá-lo se existem ferramentas relacionadas!
sequênciaÉ uma ferramenta tão pequena que pode gerar uma série de números. Você pode especificar o intervalo crescente dos números ou pode especificar o separador entre dois números adjacentes.
$ 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
Um uso mais típico
sequênciaPor exemplo, construa alguns links em um formato específico e depois use
wgetBaixe estes:
$ para i em `seq -fhttp://thns.tsinghua.edu.cn/thnsebooks/ebook73/%02g.pdf 1 21`;do wget -c $i feito;
ou
$ para i em `seq -w 1 21`;do wget -c http://thns.tsinghua.edu.cn/thnsebooks/ebook73/$i feito;
Suplemento: em
BashVersão 3 e superior, em
paracircular
emAtrás, você pode passar diretamente
{1..5}Gere números de 1 a 5 de forma mais concisa (observe que existem apenas dois pontos entre 1 e 5), por exemplo:
$ para i em {1..5}; faça echo -n $i;
Vamos primeiro dar uma definição de palavra: uma série de caracteres únicos ou múltiplos composta por letras.
Primeiro, conte o número de ocorrências de cada palavra:
$ wget -c http://tinylab.org$ cat index.html |
Em seguida, conte as 10 palavras que ocorrem com mais frequência:
$ wget -c http://tinylab.org$ cat index.html | -k 1 -r | cabeça -10 524 a 238 tag 205 href 201 classe 193 http 189 org 175 tinylab 174 www 146 div 128 títulos
ilustrar:
índice de gato.html: gera o conteúdo do arquivo index.html
sed -es/[^a-zA-Z]/n/g: Substitua caracteres não alfabéticos por espaços, mantendo apenas caracteres alfabéticos
grep -v ^$: remover linhas em branco
organizar: Organizar
uniq -c: Conte o número de linhas iguais, ou seja, o número de cada palavra
classificar -n -k 1 -r: De acordo com a primeira coluna
-k 1número
-nOrdem inversa
-rorganizar
cabeça -10: Retire as primeiras dez linhas
Duas abordagens podem ser consideradas:
Conte apenas as palavras que precisam ser contadas
Use o algoritmo acima para contar o número de todas as palavras e, em seguida, retorne ao usuário as palavras que precisam ser contadas
No entanto, ambos os métodos podem ser implementados através da seguinte estrutura. Vejamos primeiro o método um:
#!/bin/bash# statistic_words.shif [ $# -lt 1 ]; então echo Uso: nome base $0 FILE WORDS .... exit -1fiFILE=$1((WORDS_NUM=$#-1))for n in $( seq $WORDS_NUM)do shift cat $FILE | ^$ | ordenar | grep ^$1$ |
ilustrar:
se parte da condição: Requer pelo menos dois parâmetros, o primeiro arquivo de palavras e os parâmetros subsequentes são as palavras a serem contadas.
ARQUIVO=$1: Obtenha o nome do arquivo, que é a primeira string após o script
((WORDS_NUM=$#-1)): Obtenha o número de palavras, ou seja, o número total de parâmetros
$#menos o parâmetro nome do arquivo (1)
para parte do loop: Passe primeiro
sequênciaGere uma série de números de palavras que precisam ser contadas,
mudançaé uma variável interna do Shell (por favor, passe
ajudar a mudarObtenha ajuda), ele move os parâmetros passados pelo usuário da linha de comando para trás em sequência e usa o parâmetro atual como o primeiro parâmetro.
US$ 1, passou assim
US$ 1Você pode percorrer todas as palavras inseridas pelo usuário (se você pensar bem, parece um subscrito de array). Você pode considerar
mudançaSubstitua a próxima frase por
eco $ 1teste
mudançaUso
Demonstração:
$ chmod +x statistic_words.sh$ ./statistic_words.sh index.html tinylab linux python 175 tinylab 43 linux 3 python
Vejamos o método dois, só precisamos modificar
mudançaA próxima frase é suficiente:
#!/bin/bash# statistic_words.shif [ $# -lt 1 ]; then echo ERROR: você deve inserir pelo menos 2 palavras echo Usage: basename $0 FILE WORDS .... exit -1fiFILE=$1((WORDS_NUM= $#-1))for n em $(seq $WORDS_NUM)do shift cat $FILE | -es/[^a-zA-Z]/n/g | grep -v ^$ | ordenar |
Demonstração:
$ ./statistic_words.sh index.html tinylab linux python 175 tinylab 43 linux 3 python
Explicação: Obviamente, o método um é muito mais eficiente, pois encontra antecipadamente as palavras que precisam ser contadas e depois as conta, enquanto o último não é o caso. Na verdade, se você usar
grepde
-Eopção, não precisamos introduzir um loop, mas podemos fazê-lo com um comando:
$ cat index.html | sed -es/[^a-zA-Z]/n/g | grep -v ^$ | ordenar -E ^tinylab$|^linux$ |
ou
$ cat index.html | sed -es/[^a-zA-Z]/n/g | grep -v ^$ | ordenar ^tinylab$|^linux$ |
Descrição: Precisa prestar atenção
sedOs comandos podem processar arquivos diretamente sem passar
gatoA saída do comando é então passada pelo pipeline, o que pode reduzir operações desnecessárias do pipeline, de modo que o comando acima pode ser simplificado para:
$ sed -es/[^a-zA-Z]/n/g index.html | grep -v ^$ | egrep ^tinylab$|^linux$ |
Então, pode-se ver que esses comandos
sed,
grep,
único,
organizarQuão úteis eles são. Embora desempenhem apenas funções simples por si próprios, por meio de certas combinações, eles podem realizar uma variedade de coisas. A propósito, também existe um comando muito útil para contar palavras.
banheiro -w, você também pode usá-lo quando necessário.
Suplemento: Também é mencionado no livro Advanced Bash-Scripting Guide
anotacomando e
fatorcomando, como não está disponível na máquina, não há teste.
fatorO comando pode gerar todos os números primos de um determinado número. como:
$ fator 100100: 2 2 5 5
Neste ponto, termina o cálculo numérico do exemplo de programação Shell. Este artigo apresenta principalmente:
Operações inteiras, operações de ponto flutuante, geração de números aleatórios e geração de sequência na programação Shell
A diferença entre os comandos internos do Shell e os comandos externos e como visualizar seus tipos e ajuda
Várias maneiras de executar scripts Shell
Vários comandos externos do Shell comumente usados:
sed,
estranho,
grep,
único,
organizarespere
Exemplo: aumentar os números; encontrar a renda média mensal automaticamente;
PIEndereço; conte o número de palavras
Outros: Usos relacionados, como listas de comandos, testes condicionais, etc. foram abordados nos exemplos acima, leia-os com atenção.
Se você tiver tempo, revise-o.
Guia avançado de script Bash
shell treze perguntas
Doze artigos sobre noções básicas de shell
Manual SED
Manual do usuário AWK
Vários fóruns de discussão da Shell
LinuxSir.org
ChinaUnix.net
Demorei mais de 3 horas para terminar de escrever. Atualmente são 23h33. É hora de voltar para o dormitório e ir para a cama. Vou corrigir erros de digitação e adicionar algum conteúdo amanhã.
No dia 31 de outubro foram modificadas algumas redações, adicionado um exemplo de cálculo da renda média mensal familiar, acrescentado um resumo e referências e anexados todos os códigos.
A programação Shell é uma coisa muito interessante, se você pensar: no exemplo acima de cálculo da renda média mensal familiar, e depois usar
ExcelComparando este trabalho, você descobrirá que o primeiro é muito simples e descomplicado, e dá uma sensação de facilidade de uso.