Difference: TWikiBarTalk009 (1 vs. 13)

Revision 1325 Dec 2017 - Main.PauloSantana

Line: 1 to 1
 
META TOPICPARENT name="WebHome"

Pub Talk Part IX

Line: 595 to 595
       - Waiter, don't forget me and fills up my cup.
Changed:
<
<
Any doubt or lack of companionship for a beer or even to speak ill of politicians just send an email to of me.
>
>
Any doubt or lack of companionship for a beer or even to speak ill of politicians just send an email to of me.
  Thanks! \ No newline at end of file
Added:
>
>
next

-- PauloSantana - 25 Dec 2017

Revision 1216 Apr 2014 - Main.AngelaFerreira

Line: 1 to 1
 
META TOPICPARENT name="WebHome"

Pub Talk Part IX

Revision 1120 Mar 2014 - Main.AngelaFerreira

Line: 1 to 1
 
META TOPICPARENT name="WebHome"

Pub Talk Part IX

Line: 201 to 201
  c
Changed:
<
<
Note that the last two examples, because of %c=​​, was only listed one character of each chain. The =10 ahead of c no means 10 characters.
>
>
Note that the last two examples, because of %c, was only listed one character of each chain. The 10 ahead of c no means 10 characters.
 A number following the percent sign (%) means size that the chain will have after running the command.

And take for example:

Revision 1018 Mar 2014 - JulioNeves

Line: 1 to 1
 
META TOPICPARENT name="WebHome"

Pub Talk Part IX

Added:
>
>
 


Line: 5 to 6
 
Changed:
<
<
This is a very new translation from Portuguese to English. Please contribute to the development of this site indicating errors and and/or suggesting corrections and materials for this person.
>
>
This is a very new translation from Portuguese to English. Please contribute to the development of this site indicating errors and and/or suggesting corrections and materials for this person.
       - Okay, I know you will want to beer before you start, but I'm so anxious to show you what I did that I'm already asking to round up and then I'll show you.

Revision 917 Mar 2014 - Main.AngelaFerreira

Line: 1 to 1
 
META TOPICPARENT name="WebHome"

Pub Talk Part IX



Added:
>
>
This is a very new translation from Portuguese to English. Please contribute to the development of this site indicating errors and and/or suggesting corrections and materials for this person.
      - Okay, I know you will want to beer before you start, but I'm so anxious to show you what I did that I'm already asking to round up and then I'll show you.

     - Yo waiter, send two. His is no foam to not let this bad smell mustache ...

Line: 571 to 574
 In rWindows, beyond the viruses and instability, are also common filenames with a blank space and almost all uppercase. We have already seen an example of how to replace white spaces by underscores (_), next we will see how to pass them to lowercase (if you receive many files from that thing, it's best to create a script that the combination of these two).

Changed:
<
<
$ cat trocacase.sh
>
>
$ cat changecase.sh
 #!/bin/bash
Changed:
<
<
# Se o nome do arquivo tiver pelo menos uma #+ letra maiúscula, troca-a para minúscula
>
>
# If the file name has at least one #+ capital letter, return it to lowercase
 
Changed:
<
<
for Arq in *[A-Z]* # Arquivos com pelo menos 1 minúscula
>
>
for Arq in *[A-Z]* # Files with at least 1 lowercase
 do
Changed:
<
<
if [ -f "${Arq,,}" ] # Arq em minúsculas já existe?
>
>
if [ -f "${Arq,,}" ] # Arq lowercase already exists?
  then
Changed:
<
<
echo ${Arq,,} já existe
>
>
echo ${Arq,,} already exists
 else mv "$Arq" "${Arq,,}" fi done
Changed:
<
<
     - Agora já chega, o papo hoje foi muito chato porque foi muita decoreba, mas o principal é você ter entendido o que te falei e, quando precisar, consulte estes guardanapos em que rabisquei estas dicas e depois guarde-os para consultas futuras. Mas voltando à vaca fria: tá na hora de tomar outro e ver o jogo do mengão. Na próxima vou te dar moleza e só vou cobrar o seguinte: pegue a rotina pergunta.func, (a que na qual falamos no início do nosso bate papo de hoje) e otimize-a para que a variável $SN receba o valor default por expansão de parâmetros, como vimos.

     - Chico, vê se não esquece de mim e enche meu copo.

>
>
That's enough, the talk today was very boring because it was a lot of memorization, but the main thing is you have understood what I told you, and when you need it again, see these napkins in which I scribbled these tips and then save them for future reference. But back to what matters: it's time to take another and watch the football game. Next I'll give you something easy and will only charge the following: take routine question.func, (which we talked about in the beginning of our conversation today) and optimize it to the variable $SN receive the default value for parameter expansion, as we have seen.
 
Changed:
<
<
Vou aproveitar também para mandar o meu jabá: diga para os amigos que quem estiver afim de fazer um curso porreta de programação em Shell que mande um e-mail para a nossa gerencia de treinamento para informar-se.
>
>
     - Waiter, don't forget me and fills up my cup.
 
Changed:
<
<
Qualquer dúvida ou falta de companhia para um chope ou até para falar mal dos políticos é só mandar um e-mail para mim.
>
>
Any doubt or lack of companionship for a beer or even to speak ill of politicians just send an email to of me.
 
Changed:
<
<
Valeu!
>
>
Thanks!

Revision 817 Mar 2014 - Main.AngelaFerreira

Line: 1 to 1
 
META TOPICPARENT name="WebHome"

Pub Talk Part IX


Line: 490 to 490
 The idea was to catch everything the first = the , but what was exchanged was everything until the last =the. This could be solved in several ways, here are some:

Changed:
<
<
$ echo ${cadeia/*po/Conversa} Conversa de Botequim $ echo ${cadeia/????/Conversa} Conversa de Botequim
>
>
$ echo ${chain/*po/Conversation} Pub Conversation $ echo ${chain/????/Conversation} Pub Conversation
 
Changed:
<
<
  • Trocando todas as ocorrências de uma subcadeia por outra. Quando fazemos:
>
>
  • Replacing all occurrences of a subchain with another. When we do::
 
Changed:
<
<
$ echo ${cadeia//o/a} Papa de Batequim
>
>
$ echo ${chain//a/o} Pub Tolk
 
Changed:
<
<
Trocamos todos as letras o por a. Veja agora um script para tirar espaços em branco dos nomes dos arquivos.
>
>
We exchanged all letters a from o. See now a script to remove white spaces from file names.
 
Changed:
<
<
$ cat TiraBranco.sh
>
>
$ cat Removewhite.sh
 #!/bin/bash
Changed:
<
<
# Renomeia arquivos com espaços nem branco #+ no nome, trocando-os por sublinhado (_). Erro=0
>
>
# Rename files with white space #+ on the name, replacing them by underscores (_). Error=0
 for Arq in *' '* do [ -f ${Arq// /_} ] && {
Changed:
<
<
echo $Arq não foi renomeado Erro=1
>
>
echo $Arq not been renamed Error=1
  continue } mv "$Arq" "${Arq// /_}"
Changed:
<
<
done 2> /dev/null # Caso não exista arquivo com brancos o for dá erro exit $Erro
>
>
done 2> /dev/null # If there is no whites file with the command for gives error exit $Error
 
Changed:
<
<
  • Trocando uma subcadeia no início ou no fim de uma variável. Para trocar no início fazemos:
>
>
  • Replacing a subchain at the beginning or end of a variable. To change the beginning we do:
 
Changed:
<
<
$ echo $Passaro
>
>
$ echo $Bird
 quero quero
Changed:
<
<
$ echo "Como diz o sulista - "${Passaro/#quero/não} Como diz o sulista - não quero
>
>
$ echo "As the man from southern Brazil says - "${Bird/#want/not} As the man from southern Brazil says - not want
 
Changed:
<
<
Para trocar no final fazemos:
>
>
To change the end we do:
 
Changed:
<
<
$ echo "Como diz o nordestino - "${Passaro/%quero/não} Como diz o nordestino - quero não
>
>
$ echo "As the man from northern Brazil says - "${Bird/%want/not} As the man from northern Brazil says - not want
 
Changed:
<
<
Essas expansões foram introduzidas a partir do Bash 4.0 e modificam a caixa das letras do texto que está sendo expandido. Quando usamos circunflexo (^), a expansão é feita para maiúsculas, quando usamos vírgula (,), a expansão é feita para minúsculas e quando usamos til (~) a expansão troca a caixa das letras.
>
>
These expansions were introduced from the Bash 4.0 and change the letter case of the text being expanded. When we use caret (^), the expansion is made to uppercase when using comma (,), the expansion is made for lowercase and when we use tilde (~) the expansion changes the case of the letters.
 
Changed:
<
<
$ Nome="botelho" $ echo ${Nome^}
>
>
$ Name="botelho" $ echo ${Name^}
 Botelho $ echo ${Nome^^} BOTELHO
Changed:
<
<
$ Nome="botelho carvalho" $ echo ${Nome^}
>
>
$ Name="botelho carvalho" $ echo ${Name^}
 Botelho carvalho
Changed:
<
<
$ echo ${Nome~} # Capitalizando $Nome
>
>
$ echo ${Name~} # Capitalizing $Name
 Botelho Carvalho
Changed:
<
<
$ Coisa="AAAbbb cccDDD" $ echo ${Coisa~}
>
>
$ Thing="AAAbbb cccDDD" $ echo ${Thing~}
 aAAbbb CccDDD
Changed:
<
<
$ echo ${Coisa~~}
>
>
$ echo ${Thing~~}
 aaaBBB CCCddd
Changed:
<
<
Um fragmento de script que pode facilitar a sua vida:
>
>
A fragment of script that can make your life easier:
 
Changed:
<
<
read -p "Deseja continuar (s/n)? "
>
>
read -p "Do you wish to continue? (y/n)? "
 ${REPLY^} == N? && exit
Changed:
<
<
Esta forma evita testarmos se a resposta dada foi um N (maiúsculo) ou um n (minúsculo).
>
>
This form avoids we test whether the answer given was a N (uppercase) or an n (lowercase).
 
Changed:
<
<
No rWindows, além dos vírus e da instabilidade, também são frequentes nomes de arquivos com espaços em branco e quase todos em maiúsculas. Já vimos um exemplo de como trocar os espaços em branco por sublinha (_), no próximo veremos como passá-los para minúsculas (se você recebe muitos arquivos daquela coisa, o melhor é criar um script que seja a junção desses dois).
>
>
In rWindows, beyond the viruses and instability, are also common filenames with a blank space and almost all uppercase. We have already seen an example of how to replace white spaces by underscores (_), next we will see how to pass them to lowercase (if you receive many files from that thing, it's best to create a script that the combination of these two).
 
$ cat trocacase.sh

Revision 714 Mar 2014 - Main.AngelaFerreira

Line: 1 to 1
 
META TOPICPARENT name="WebHome"

Pub Talk Part IX


Line: 459 to 459
 
  • The use of percentage (%) is like looking the tic-tac-toe (#) in the mirror, that is, are symmetrical. So let's look at an example to prove it:

Changed:
<
<
$ echo $cadeia Papo de Botequim $ echo ${cadeia%' '*} Papo de $ echo ${cadeia%%' '*} Papo
>
>
$ echo $chain Pub Talk $ echo ${chain%' '*} Talk $ echo ${chain%%' '*} Talk
 
Changed:
<
<
  • Para trocar primeira ocorrência de uma subcadeia em uma cadeia por outra:
>
>
  • To replace the first occurrence of a subchain in a chain for another:
 
Changed:
<
<
$ echo $cadeia Papo de Botequim $ echo ${cadeia/de/no} Papo no Botequim $ echo ${cadeia/de /} Papo Botequim
>
>
$ echo $chain Pub Talk $ echo ${chain/of/no} Pub Talk $ echo ${chain/of /} Pub Talk
 
Changed:
<
<
Neste caso preste a atenção quando for usar metacaracteres, eles são gulosos! Eles sempre combinarão com a maior possibilidade, veja o exemplo a seguir onde a intenção era trocar Papo de Botequim por Conversa de Botequim:
>
>
In this case pay attention when using metacharacters, they are greedy! They always will combine with greater possibility. See the following example where the intent was to exchange Pub Talk by Pub Conversation:
 
Changed:
<
<
$ echo $cadeia Papo de Botequim $ echo ${cadeia/*o/Conversa} Conversatequim
>
>
$ echo $chain Pub Talk $ echo ${chain/*the/Conversation} Conversapub
 
Changed:
<
<
A idéia era pegar tudo até o primeiro o, mas o que foi trocado foi tudo até o último o. Isto poderia ser resolvido de diversas maneiras, veja algumas:
>
>
The idea was to catch everything the first = the , but what was exchanged was everything until the last =the. This could be solved in several ways, here are some:
 
$ echo ${cadeia/*po/Conversa}

Revision 613 Mar 2014 - Main.AngelaFerreira

Line: 1 to 1
 
META TOPICPARENT name="WebHome"

Pub Talk Part IX


Line: 424 to 424
 Pub Talk
Changed:
<
<
Neste exemplo foi suprimido à esquerda tudo que casasse com a menor ocorrência da expressão *' ', ou seja, tudo até o primeiro espaço em branco.
>
>
In this instance was suppressed to the left everything corresponded with the lowest occurrence of the expression *' ', that is, everything until the first space in blank.
 
Changed:
<
<
Estes exemplos também poderiam ser escritos sem protegermos o espaço da interpretação do Shell (mas prefiro protegê-lo para facilitar a legibilidade do código), veja:
>
>
These examples could also be written without us protect the space of Shell interpretation (but I prefer to protect it for readability of the code), see:
 
Changed:
<
<
$ echo ${cadeia#* } de Botequim $ echo "Conversa "${cadeia#* } Conversa de Botequim
>
>
$ echo ${chain#* } Pub $ echo "Talk "${chain#* } Pub Talk
 
Changed:
<
<
Repare que na construção de expr é permitido o uso de metacaracteres.
>
>
Note that in building of expr the use of metacharacters is allowed.
 
Changed:
<
<
  • Utilizando o mesmo valor da variável $cadeia, observe como faríamos para termos somente Botequim:
>
>
  • Using the same variable value $chain note how we would to have only Pub:
 
Changed:
<
<
$ echo ${cadeia##*' '} Botequim $ echo "Vamos 'Chopear' no "${cadeia##*' '} Vamos 'Chopear' no Botequim
>
>
$ echo ${chain##*' '} Pub $ echo "Let's go 'drink' in "${chain##*' '} Let's go 'drink' in the Pub
 
Changed:
<
<
Desta vez suprimimos à esquerda de cadeia a maior ocorrência da expressão expr. Assim como no caso anterior, o uso de metacaracteres é permitido.
>
>
This time, we suppress to the left of the chain the higher occurrence of the expression expr. As in the previous case, the use of metacharacters is allowed.
 
Changed:
<
<
Outro exemplo mais útil: para que não apareça o caminho (path) completo do seu programa (que, como já sabemos está contido na variável $0) em uma mensagem de erro, inicie o seu texto da seguinte forma:
>
>
Another more useful example: do not appear for the full path (path) of your program (which as we know is contained in the variable $0) in an error message, start your text as follows:
 
Changed:
<
<
echo Uso: ${0##*/} texto da mensagem de erro
>
>
echo Use: ${0##*/} text of the error message
 
Changed:
<
<
Neste exemplo seria suprimido à esquerda tudo até a última barra (/) do caminho (path), desta forma sobrando somente o nome do programa.
>
>
In this example would be suppressed to the left everything until the last bar (/) the path (path) thus leaving only the name of the program.
 
Changed:
<
<
  • O uso do percentual (%) é como se olhássemos o jogo-da-velha (#) no espelho, isto é, são simétricos. Então vejamos um exemplo para provar isso:
>
>
  • The use of percentage (%) is like looking the tic-tac-toe (#) in the mirror, that is, are symmetrical. So let's look at an example to prove it:
 
$ echo $cadeia

Revision 513 Mar 2014 - Main.AngelaFerreira

Line: 1 to 1
 
META TOPICPARENT name="WebHome"

Pub Talk Part IX


Line: 57 to 57
  clear echo "
Changed:
<
<
+----------------------------------------------------+
>
>
+-----------------------------------------+
   | List All Songs of a Particular Artist |
Changed:
<
<
 | ----- ----- -- ------- -- -- ----------- ------- |
>
>
 | ---- --- ----- -- - ---------- ------ |
   | |  | Enter the Artist: |
Changed:
<
<
+----------------------------------------------------+"
>
>
+-----------------------------------------+"
 while true do tput cup 5 51; tput ech 31 # ech=Erase chars (31 characters to not erase vertical bar)
Line: 113 to 113
      - Gosh, you got it all! But I liked the way you solved the problem and structured the program. It was more laborious but the presentation was very cool and you explored tput options. Let's test the result with an album Emerson, Lake & Palmer I have registered.
Changed:
<
<
+----------------------------------------------------+
>
>
+----------------------------------------------+
 
List All Songs of a Particular Artist
Changed:
<
<
----- ----- -- ------- -- -- ----------- -------
>
>
---- --- ----- -- - ---------- ------
 
 
Enter the Artist: Emerson, Lake & Palmer
Changed:
<
<
+----------------------------------------------------+
>
>
+----------------------------------------------+
 
Toccata
 
Jerusalem
Line: 126 to 126
 
 
Benny The Bouncer
Karn Evil 9
Changed:
<
<
+-----------Enter Something to New Query------------+
>
>
+---------Enter Something to New Query---------+
 

Improving writing

Revision 412 Mar 2014 - Main.AngelaFerreira

Line: 1 to 1
 
META TOPICPARENT name="WebHome"

Pub Talk Part IX


Line: 141 to 141
 

Onde:

Changed:
<
<
format - it's a string that contains three types of object:
>
>
format - it's a chain that contains three types of object:
 
  1. simple character;
  2. characters for format specification;
  3. escape sequence in standard C language.
Changed:
<
<
Argument - it's the string to be printed under the control of format.
>
>
Argument - it's the chain to be printed under the control of format.
  Each of the characters used for specifying format is preceded by the character %, then there follows the specification format according to the table:
Line: 159 to 159
 
o  Number in octal system  
f  Number with decimal point (float)  
g The lower among the formats %e and %f with suppression of no significant zeros.
Changed:
<
<
s  Character string  
>
>
s  Character chain  
 
x  Number in hexadecimal system  
%  Prints a %. No conversion exists  
Line: 184 to 184
 $ printf "%c" "1 character" 1$ Wrong! Listed only 1 character and not jumped row to the end $ printf "%c\n" "1 character"
Changed:
<
<
1 Jumped row but not yet listed the full string
>
>
1 Jumped row but not yet listed the full chain
 $ printf "%c character\n" 1 1 character This is the correct way the %c received the 1 $ a=2
Line: 197 to 197
  c
Changed:
<
<
Note that the last two examples, because of %c=​​, was only listed one character of each string. The =10 ahead of c no means 10 characters. A number following the percent sign (%) means size that the string will have after running the command.
>
>
Note that the last two examples, because of %c=​​, was only listed one character of each chain. The =10 ahead of c no means 10 characters. A number following the percent sign (%) means size that the chain will have after running the command.
  And take for example:
Line: 337 to 337
  I am the time that memory was a valuable asset that was so expensive. So to get a S or N I don't usually allocate a special space and therefore, I caught what was typed in the variable $REPLY.
Changed:
<
<

Expansion parameters

>
>

Expansion of parameters

 
Changed:
<
<
Bem, muito do que vimos até agora são comandos externos ao Shell. Eles quebram o maior galho, facilitam a visualização, manutenção e depuração do código, mas não são tão eficientes quanto os intrínsecos (built-ins). Quando o nosso problema for performance, devemos dar preferência ao uso dos intrínsecos e a partir de agora vou te mostrar algumas técnicas para o teu programa pisar no acelerador.
>
>
Well, a lot of what we have seen so far are external to Shell commands. They help us facilitate the visualization, maintenance and debugging code, but are not as efficient as the intrinsic (built-ins). When our problem is performance, we should give preference to the use of intrinsic and from now on I will show you some techniques for your program step on the accelerator.
 
Changed:
<
<
Na tabela e exemplos a seguir, veremos uma série de construções chamadas expansão (ou substituição) de parâmetros (Parameter Expansion), que substituem instruções como o cut, o expr, o tr, o sed e outras de forma mais ágil.
>
>
In the following examples and table, we will see a number of buildings expansion calls (or replacement) of parameters (Parameter Expansion), which replace instructions as the cut, the expr, the tr, the sed and others more agile.
 
Changed:
<
<
Expansão de parâmetros
  ${cadeia~~}   Troca a caixa de todas as letra de cadeia (a partir do bash 4.0)
  Expressão   Resultado esperado
  ${var:-padrao}   Se var não tem valor, o resultado da expressão é padrao
  ${#cadeia}   Tamanho de $cadeia
  ${cadeia:posicao}   Extrai uma subcadeia de $cadeia a partir de posicao. Origem zero
  ${cadeia:posicao:tamanho}   Extrai uma subcadeia de $cadeia a partir de posicao com tamanho igual a tamanho. Origem zero
  ${cadeia#expr}   Corta a menor ocorrência de $cadeia à esquerda da expressão expr
  ${cadeia##expr}   Corta a maior ocorrência de $cadeia à esquerda da expressão expr
  ${cadeia%expr}   Corta a menor ocorrência de $cadeia à direita da expressão expr
  ${cadeia%%expr}   Corta a maior ocorrência de $cadeia à direita da expressão expr
  ${cadeia/subcad1/subcad2}   Troca em $cadeia a primeira ocorrência de subcad1 por subcad2
  ${cadeia//subcad1/subcad2}   Troca em $cadeia todas as ocorrências de subcad1 por subcad2
  ${cadeia/#subcad1/subcad2}   Se subcad1 combina com o início de $cadeia, então é trocado por subcad2
  ${cadeia/%subcad1/subcad2}   Se subcad1 combina com o fim de $cadeia, então é trocado por subcad2
  ${cadeia^}   Coloca a primeira letra de cadeia em maiúscula (a partir do bash 4.0)
  ${cadeia^^}   Coloca todas as letra de cadeia em maiúscula (a partir do bash 4.0)
  ${cadeia,}   Coloca a primeira letra de cadeia em minúscula (a partir do bash 4.0)
  ${cadeia,,}   Coloca todas as letra de cadeia em minúscula (a partir do bash 4.0)
  ${cadeia~}   Troca a caixa de cada primeira letra das palavras de cadeia (a partir do bash 4.0)
>
>
Expansion of parameters
  ${chain~~}   Swaps the box every letter chain (from the bash 4.0
  Expression   Expected Result
  ${var:-default}   If var hasn't value, the result of the expression is default
  ${#chain}   Size of $chain
  ${chain:position}   Extracts a subchain $chain from position. Origin zero
  ${chain:posicion:size}   Extracts a subchain $chain from position with size equal to size. Origin zero
  ${chain#expr}   Cuts the lower occurrence of $chain to the left of expression expr
  ${chain##expr}   Cuts the most occurrence of $chain to the left of expression expr
  ${chain%expr}   Cuts the lower occurrence of $chain to the right of expression expr
  ${chain%%expr}   Cuts the most occurrence of $chain to the right of expression expr
  ${chain/subcad1/subcad2}   Exchange in $chain the first occurrence of subcad1 by subcad2
  ${chain//subcad1/subcad2}   Exchange in $chain all occurrences of subcad1 by subcad2
  ${chain/#subcad1/subcad2}   If subcad1 combines with beginning of $chain, then it is replaced by subcad2
  ${chain/%subcad1/subcad2}   If subcad1 combines with the end of $chain, then it is replaced by subcad2
  ${chain^}   Puts the first letter of chain in uppercase (from the bash 4.0)
  ${chain^^}   Puts all letters of chain in uppercase (from the bash 4.0)
  ${chain,}   Puts the first letter of chain in lowercase (from the bash 4.0)
  ${chain,,}   Puts all letters of chain in lowercase (from the bash 4.0)
  ${chain~}   Swaps the box every first letter of words chain (from the bash 4.0)
 
Changed:
<
<
  • Se em uma pergunta o S é oferecido como valor default (padrão) e a saída vai para a variável $SN, após ler o valor podemos fazer:
>
>
  • If into a question the S is offered as default value and the output goes to the variable $SN, after reading the value we can do:
 
    SN=${SN:-S}
Changed:
<
<
Desta forma se o operador deu um simples <ENTER> para confirmar que aceitou o valor default, após executar esta instrução, a variável terá o valor S, caso contrário, terá o valor digitado.
>
>
Thus if the operator has a simple <ENTER> to confirm that accepted the default value after executing this instruction, the variable will have the value S, otherwise, will have the value entered.
 
Changed:
<
<
  • Para sabermos o tamanho de uma cadeia:
>
>
  • To know the size of a chain:
 
Changed:
<
<
$ cadeia=0123 $ echo ${#cadeia}
>
>
$ chain=0123 $ echo ${#chain}
 4
Changed:
<
<
  • Para extrair de uma cadeia da posição um até o final fazemos:
>
>
  • To extract a chain from one position to the end do:
 
Changed:
<
<
$ cadeia=abcdef $ echo ${cadeia:1}
>
>
$ chain=abcdef $ echo ${chain:1}
 bcdef
Changed:
<
<
Repare que a origem é zero e não um.
>
>
Notice that the origin is zero and not one.
 
Changed:
<
<
  • Na mesma variável $cadeia do exemplo acima, para extrair 3 caracteres a partir da 2ª posição:
>
>
  • In the same variable = $ chain = of the above example, to extract 3 characters from the 2nd position
 
Changed:
<
<
$ echo ${cadeia:2:3}
>
>
$ echo ${chain:2:3}
 cde
Changed:
<
<
Repare que novamente que a origem da contagem é zero e não um.
>
>
Notice again that the origin is zero and not one.
 
Changed:
<
<
  • Podemos também extrair do fim para o princípio
>
>
  • We can also extract of the end to the beginning
 
Changed:
<
<
$ TimeBom=Flamengo $ echo ${TimeBom: -5}
>
>
$ GoodTeam=Flamengo $ echo ${GoodTeam: -5}
 mengo
Changed:
<
<
$ echo ${TimeBom:(-5)}
>
>
$ echo ${GoodTeam:(-5)}
 mengo
Changed:
<
<
O espaço em branco ou os parênteses são obrigatórios para que o sinal de menos (-) não cole nos dois-pontos (:), que caso ocorresse, ficaria semelhante à expansão que vimos acima e que substitui uma variável vazia ou nula por um valor padrão (default), ou seja, a famosa ${var:-padrao}.
>
>
The white space or parentheses are required for the minus sign (-) not paste in the colon (:), which if it occurred, would be similar to expansion we saw above and replacing an empty or null variable with a default value (default), in other words the famous ${var:-default}.
 
Changed:
<
<
  • Para suprimir tudo à esquerda da primeira ocorrência de uma cadeia, faça:
>
>
  • To suppress everything to the left of the first occurrence of a chain, do:
 
Changed:
<
<
$ cadeia="Papo de Botequim" $ echo ${cadeia#*' '} de Botequim $ echo "Conversa "${cadeia#*' '} Conversa de Botequim
>
>
$ chain="Talk Pub" $ echo ${chain#*' '} Pub $ echo "Talk "${chain#*' '} Pub Talk
 

Neste exemplo foi suprimido à esquerda tudo que casasse com a menor ocorrência da expressão *' ', ou seja, tudo até o primeiro espaço em branco.

Revision 312 Mar 2014 - Main.AngelaFerreira

Line: 1 to 1
 
META TOPICPARENT name="WebHome"

Pub Talk Part IX


Line: 250 to 250
  I believe I did right when I decided to explain printf using examples, because I wouldn't know how to enumerate so many little rules without make for tedious reading.
Changed:
<
<

Principais Variáveis do Shell

>
>

Main Shell Variables

 
Changed:
<
<
O Bash possui diversas variáveis que servem para dar informações sobre o ambiente ou alterá-lo. Seu número é muito grande e não pretendo mostrar todas, mas uma pequena parte que pode lhe ajudar na elaboração de scripts. Então aí vão as principais:
>
>
Bash has several variables that serve to give information about the environment or change it. Their number is very large and does not intend to show all but a small part that can help you in developing scripts. So here goes the main ones:
 
Changed:
<
<
Principais variáveis do Bash
TMOUT Se tiver um valor maior do que zero, este valor será tomado como o padrão de timeout do comando read. No prompt, este valor é interpretado como o tempo de espera por uma ação antes de expirar a sessão. Supondo que a variável contenha 30, o Shell dará logout após 30 segundos de prompt sem nenhuma ação.
      Variável Conteúdo
CDPATH Contém os caminhos que serão pesquisados para tentar localizar um diretório especificado. Apesar desta variável ser pouco conhecida, seu uso deve ser incentivado por poupar muito trabalho, principalmente em instalações com estrutura de diretórios com bastante níveis.
HISTSIZE Limita o número de instruções que cabem dentro do arquivo de histórico de comandos (normalmente .bash_history mas efetivamente é o que está armazenado na variável $HISTFILE). Seu valor default é 500.  
HOSTNAME O nome do host corrente (que também pode ser obtido com o comando uname -n).
LANG Usada para determinar a língua falada no pais (mais especificamente categoria do locale).
LINENO O número da linha do script ou da função que está sendo executada, seu uso principal é para dar mensagens de erro juntamente com as variáveis $0 (nome do programa) e $FUNCNAME (nome da função em execução)
LOGNAME Armazena o nome de login do usuário.
MAILCHECK Especifica, em segundos, a freqüência que o Shell verificará a presença de correspondências nos arquivos indicados pela variáveis $MAILPATH ou $MAIL. O tempo padrão é 60 segundos. Uma vez este tempo expirado, o Shell fará esta verificação antes de exibir o próximo prompt primário (definido em $PS1). Se esta variável estiver sem valor ou com um valor menor ou igual a zero, a verificação de novas correspondências não será efetuada.
PATH Caminhos que serão pesquisados para tentar localizar um arquivo especificado. Como cada script é um arquivo, caso use o diretório corrente (.) na sua variável $PATH, você não necessitará de usar o ./scrp para que scrp seja executado. Basta fazer scrp. Este é o modo que procedo aqui no Botequim.
PIPESTATUS É uma variável do tipo vetor (array) que contém uma lista valores de código de retorno do último pipeline executado, isto é, um array que abriga cada um dos $? de cada instrução do último pipeline.
PROMPT_COMMAND Se esta variável receber uma instrução, toda vez que você der um <ENTER> direto no prompt principal ($PS1), este comando será executado. É útil quando se está repetindo muito uma determinada instrução.
PS1 É o prompt principal. No "Papo de Botequim" usamos os seus defaults: $ para usuário comum e # para root, mas é muito freqüente que ele esteja customizado. Uma curiosidade é que existe até concurso de quem programa o $PS1 mais criativo. (clique para dar uma googlada)
PS2 Também chamado prompt de continuação, é aquele sinal de maior (>) que aparece após um <ENTER> sem o comando ter sido encerrado.
PWD Possui o caminho completo ($PATH) do diretório corrente. Tem o mesmo efeito do comando pwd.
RANDOM Cada vez que esta variável é acessada, devolve um número inteiro, que é um randômico entre 0 e 32767.
REPLY Use esta variável para recuperar o último campo lido, caso ele não tenha nenhuma variável associada.
SECONDS Esta variável contém a quantidade de segundos que o Shell corrente está de pé. Use-a somente para esnobar um usuários daquilo que chamam de sistema operacional, mas necessita de boots freqüentes. smile
>
>
Main Bash Variables
TMOUT If it has a value greater than zero, this value is taken as the default timeout read command. In the prompt, this value is interpreted as the waiting time for an action before the session expires. Supposing that the variable contains 30, the Shell will logout after 30 seconds without any prompt action.
      Variable Content
CDPATH Contains the paths to be searched to try to find a specified directory. Although this variable is little known, their use should be encouraged by saving a lot of work, especially in installations with directory structure with enough levels.
HISTSIZE Limits the number of instructions that fit within the command history file (normally .bash_history but effectively it's what is stored in the variable $=HISTFILE=). Your default value is 500.  
HOSTNAME The host name of the current (which may also be obtained from the uname -n command).
LANG Used to determine the language spoken in the country (more specifically locale category).
LINENO The row number of the script or function being executed, their main use it is to give error messages along with the variables $0 (program name) and $FUNCNAME (name of executing function)
LOGNAME Stores the user's login name.
MAILCHECK Specifies, in seconds, how often the Shell will check for mail in the files specified by variables $MAILPATH or $MAIL. The default time is 60 seconds. Once this time expires, the Shell will make this check before displaying the next primary prompt (defined in $PS1). If that it's valueless or less than or equal to zero, checking for new mail will not be effected.
PATH Paths that will be searched to try to find a specified file. How each script is a file, if you use the current directory (.) in your $PATH variable, you'll not need to use the ./scrp to scrp runs. Just do scrp. This is the way I proceed here in Pub.
PIPESTATUS It's a variable of type vector (array) containing a list of return code values pipeline the last run, that is, array one that shelters each $? each statement last pipeline.
PROMPT_COMMAND If this variable receives a direction, every time you give a <ENTER> direct to the main prompt ($PS1), this command will run. It's useful when you're repeating much a given instruction.
PS1 It is the main prompt. In "Pub Talk" we use their defaults: $ for common user and # for root, but most often it's customized. A curiosity is that exists until competition of who the program $PS1 more creatively . (click here to see in Google)
PS2 Also called continuation prompt, is one sign of greater (>) that appears after a <ENTER> without the command has been closed.
PWD Contains the full path ($PATH) the current directory. Has the same effect of the pwd command.
RANDOM Each time this variable is accessed, it returns an integral number, which is a random between 0 and 32767.
REPLY Use this variable to retrieve the last field read, if it has no variable associated.
SECONDS This variable contains the number of seconds that the current Shell is standing. Use it only to ignore a user what we call the operating system, but requires frequent boots. smile
 

  • CDPATH
Line: 289 to 289
 /usr/local/bin
Changed:
<
<
Como /usr/local estava na minha variável $CDPATH, e não existia o diretório bin em nenhum dos seus antecessores (., .. e ~), o cd foi executado para /usr/local/bin
>
>
As /usr/local was in my variable $CDPATH, and there wasn't bin directory in any of it's predecessors (., .. and ~), the cd was run for /usr/local/bin
 
  • LANG
Line: 300 to 300
 Qui Abr 14 11:55:14 BRT 2005
Changed:
<
<
Com a especificação da variável LANG=pt_BR (português do Brasil), a data passou a ser informada no padrão brasileiro. É interessante observarmos que não foi usado ponto-e-vírgula (;) para separar a atribuição de LANG do comando date.
>
>
With the specifying the variable LANG=pt_BR (Portuguese from Brazil), the date passed to be informed in the Brazilian standard. It's interesting to note that it wasn't used semicolon (;) to separate the assignment LANG of date command.
 
  • PIPESTATUS
Line: 313 to 313
 0 1
Changed:
<
<
Neste exemplo mostramos que o usuário botelho não estava "logado", em seguida executamos um pipeline que procurava por ele. Usa-se a notação [*] em um array para listar todos os seus elementos, e desta forma vimos que a primeira instrução (who) foi bem sucedida (código de retorno 0) e a seguinte (grep), não (código de retorno 1).
>
>
In this example we showed that the user botelho wasn't "logged" then we executed a pipeline that were looking for it. Uses the notation [*] in a array to list all it's elements, and thus we saw that the first statement (who) was successful (return code 0) and the next (grep) not (return code 1).
 
  • RANDOM
Changed:
<
<
Para gerar randomicamente um inteiro entre 0 e 100, fazemos:
>
>
To generate randomly an integer between 0 and 100, do:
 
$ echo $((RANDOM%101)) 73
Changed:
<
<
Ou seja pegamos o resto da divisão por 101 do número randômico gerado, porque o resto da divisão de qualquer número por 101 varia entre 0 e 100.
>
>
That is, we took the rest of the division by 101 of the random number generated, because the remainder of dividing any number by 101 varies from 0 and 100.
 
  • REPLY
Line: 335 to 335
 N
Changed:
<
<
Eu sou do tempo que memória era um bem precioso que custava muuuuito caro. Então para pegar um S ou um N, não costumo a alocar um espaço especial e assim sendo, pego o que foi digitado na variável $REPLY.
>
>
I am the time that memory was a valuable asset that was so expensive. So to get a S or N I don't usually allocate a special space and therefore, I caught what was typed in the variable $REPLY.
 
Changed:
<
<

Expansão de parâmetros

>
>

Expansion parameters

  Bem, muito do que vimos até agora são comandos externos ao Shell. Eles quebram o maior galho, facilitam a visualização, manutenção e depuração do código, mas não são tão eficientes quanto os intrínsecos (built-ins). Quando o nosso problema for performance, devemos dar preferência ao uso dos intrínsecos e a partir de agora vou te mostrar algumas técnicas para o teu programa pisar no acelerador.

Revision 212 Mar 2014 - Main.AngelaFerreira

Line: 1 to 1
 
META TOPICPARENT name="WebHome"

Pub Talk Part IX


Line: 131 to 131
 

Improving writing

Changed:
<
<
    - Ufa! Agora você já sabe tudo sobre leitura, mas sobre escrita está apenas engatinhando. Já sei que você vai me perguntar:
    - Ora, não é com o comando echo e com os redirecionamentos de saída que se escreve?
>
>
    - Whew! Now you know all about reading, but about writing is just beginning. I know you will ask me:
    - Well, is not with the echo command and with the output redirections you write?
 
Changed:
<
<
É, com estes comandos você escreve 90% das coisas necessárias, porém se precisar de escrever algo formatado eles lhe darão muito trabalho. Para formatar a saída veremos agora uma instrução muito interessante e que é de execução muito veloz, porque, assim como o echo, é um comando intrínseco (builtin) do Shell - é o printf - sua sintaxe é a seguinte:
>
>
It's with these commands you write 90% of the necessary things, but if you need something to write formatted they will give you a lot of work. To format the output now we will see a very interesting statement and it's very fast implementation, because, like the echo, it's an intrinsic command (builtin) of Shell - it's the printf - it's syntax is as follows:
 
Changed:
<
<
printf formato [argumento...]
>
>
printf format [argument...]
 

Onde:

Changed:
<
<
formato - é uma cadeia de caracteres que contem 3 tipos de objeto:
  1. caracteres simples;
  2. caracteres para especificação de formato;
  3. seqüência de escape no padrão da linguagem C.
Argumento - é a cadeia a ser impressa sob o controle do formato.
>
>
format - it's a string that contains three types of object:
  1. simple character;
  2. characters for format specification;
  3. escape sequence in standard C language.
Argument - it's the string to be printed under the control of format.
 
Changed:
<
<
Cada um dos caracteres utilizados para especificação de formato é precedido pelo caracter % e logo a seguir vem a especificação de formato de acordo com a tabela:
>
>
Each of the characters used for specifying format is preceded by the character %, then there follows the specification format according to the table:
 
Changed:
<
<
Tabela dos Caracteres de Formatação do printf
%  Imprime um %. Não existe nenhuma conversão  
  Letra     A expressão será impressa como:
c  Simples caractere  
d  Número no sistema decimal  
e  Notação científica exponencial  
f  Número com ponto decimal (float)  
g O menor entre os formatos %e e %f com supressão dos zeros não significativos
o  Número no sistema octal  
s  Cadeia de caracteres  
x  Número no sistema hexadecimal  
>
>
Table of Formatting Characters printf
%  Prints a %. No conversion exists  
  Letter     The expression will be printed as:
c  simple character  
d  Number in the decimal system  
e  Exponential scientific notation  
f  Number with decimal point (float)  
g The lower among the formats %e and %f with suppression of no significant zeros.
o  Number in octal system  
s  Character string  
x  Number in hexadecimal system  
 
Changed:
<
<
As seqüências de escape padrão da linguagem C são sempre precedidas por um contra-barra (\) e as reconhecidas pelo comando printf são:
>
>
The sequences of the C language standard escape are always preceded by a backslash (\) and recognized by the printf command are:
 
Changed:
<
<
Sequencias de Escape do printf
t   Avança para a próxima marca de tabulação  
  Seqüência     Efeito  
a   Soa o beep  
b   Volta uma posição (backspace)  
f   Salta para a próxima página lógica (form feed)  
n   Salta para o início da linha seguinte (line feed)  
r   Volta para o início da linha corrente (carriage return)  
>
>
Sequences Escape printf
t   Advances to the next tab stop  
  Sequence     Effect  
a   The beep sounds  
b   Back one position (backspace)  
f   Jump to the next logical page (form feed)  
n   Jumps to the beginning of the next row (line feed)  
r   Back to the beginning of current line (carriage return)  
 
Changed:
<
<
Não acabou por aí não! Tem muito mais coisa sobre a instrução, mas como é muito cheio de detalhes e, portanto, chato para explicar e, pior ainda para ler ou estudar, vamos passar direto aos exemplos com seus comentários, que não estou aqui para encher o saco de ninguém.
>
>
Not end here! It has a lot more going about instruction, but as it is very full of details and therefore boring to explain, and even worse to read or study, let's jump right to the examples with your comments, I'm not here to bother anyone.
 
Changed:
<
<
$ printf "%c" "1 caracter" 1$ Errado! Só listou 1 caractere e não saltou linha ao final $ printf "%c\n" "1 caracter" 1 Saltou linha mas ainda não listou a cadeia inteira $ printf "%c caractere\n" 1 1 caractere Esta é a forma correta o %c recebeu o 1
>
>
$ printf "%c" "1 character" 1$ Wrong! Listed only 1 character and not jumped row to the end $ printf "%c\n" "1 character" 1 Jumped row but not yet listed the full string $ printf "%c character\n" 1 1 character This is the correct way the %c received the 1
 $ a=2
Changed:
<
<
$ printf "%c caracteres\n" $a 2 caracteres O %c recebeu o valor da variável $a $ printf "%10c caracteres\n" $a          2 caracteres $ printf "%10c\n" $a caracteres
>
>
$ printf "%c character\n" $a 2 character The %c received the value of the $a variable $ printf "%10c character\n" $a          2 character $ printf "%10c\n" $a character
          2 c
Changed:
<
<
Repare que nos dois últimos exemplos, em virtude do %c, só foi listado um caracter de cada cadeia. O 10 à frente do c, não significa 10 caracteres. Um número seguindo o sinal de percentagem (%) significa o tamanho que a cadeia terá após a execução do comando.
>
>
Note that the last two examples, because of %c=​​, was only listed one character of each string. The =10 ahead of c no means 10 characters. A number following the percent sign (%) means size that the string will have after running the command.
 
Changed:
<
<
E tome de exemplo:
>
>
And take for example:
 
$ printf "%d\n" 32 32 $ printf "%10d\n" 32
Changed:
<
<
32 Preenche com brancos à esquerda e não com zeros
>
>
32 Fills with white left and with no zeros
 $ printf "%04d\n" 32
Changed:
<
<
0032 04 após % significa 4 dígitos com zeros à esquerda
>
>
0032 04 after % means 4 digits with leading zeros
 $ printf "%e\n" $(echo "scale=2 ; 100/6" | bc)
Changed:
<
<
1.666000e+01 O default do %e é 6 decimais
>
>
1.666000e+01 The default of %e it's 6 decimal
 $ printf "%.2e\n" `echo "scale=2 ; 100/6" | bc`
Changed:
<
<
1.67e+01 O .2 especificou duas decimais
>
>
1.67e+01 The .2 specifies two decimal
 $ printf "%f\n" 32.3
Changed:
<
<
32.300000 O default do %f é 6 decimais
>
>
32.300000 The default of %f it's 6 decimal
 $ printf "%.2f\n" 32.3
Changed:
<
<
32.30 O .2 especificou duas decimais
>
>
32.30 The .2 specifies two decimal
 $ printf "%.3f\n" `echo "scale=2 ; 100/6" | bc`
Changed:
<
<
33.330 O bc devolveu 2 decimais. o printf colocou 0 à direita
>
>
33.330 The bc returned 2 decimals. The printf put 0 on the right
 $ printf "%o\n" 10
Changed:
<
<
12 Converteu o 10 para octal
>
>
12 Converted the 10 to octal
 $ printf "%03o\n" 27
Changed:
<
<
033 Assim a conversão fica com mais jeito de octal, né?
>
>
033 So the conversion becomes more like octal, right?
 $ printf "%s\n" Peteleca Peteleca $ printf "%15s\n" Peteleca
Changed:
<
<
Peteleca Peteleca com 15 caracteres enchidos com brancos
>
>
Peteleca Peteleca with 15 characters filled with whites
 $ printf "%-15sNeves\n" Peteleca
Changed:
<
<
Peteleca Neves O menos (-) encheu à direita com brancos
>
>
Peteleca Neves The minus (-) filled the right with whites
 $ printf "%.3s\n" Peteleca
Changed:
<
<
Pet 3 trunca as 3 primeiras
>
>
Pet 3 truncates the first 3
 $ printf "%10.3sa\n" Peteleca
Changed:
<
<
Peta Pet com 10 caracteres concatenado com a (após o s) $ printf "EXEMPLO %x\n" 45232 EXEMPLO b0b0 Transformou para hexa mas os zeros não combinam
>
>
Peta Pet with 10 characters concatenated with (after the s) $ printf "EXAMPLE %x\n" 45232 EXAMPLE b0b0 Turned to hexa but the zeros don't combine
 $ printf "EXEMPLO %X\n" 45232
Changed:
<
<
EXEMPLO B0B0? Assim disfarçou melhor (repare o X maiúsculo)
>
>
EXAMPLE B0B0? Thus disguised better (note the X caps)
 $ printf "%X %XL%X\n" 49354 192 10 C0CA? C0LA?
Changed:
<
<
O último exemplo não é marketing e é bastante completo, vou comentá-lo passo-a-passo:
  1. O primeiro %X converteu 49354 em hexadecimal resultando C0CA (leia-se "cê", "zero", "cê" e "a");
  2. Em seguida veio um espaço em branco seguido por outro %XL. O %X converteu o 192 dando como resultado C0 que com o L fez C0L;
  3. E finalmente o último %X transformou o 10 em A.
>
>
The last example isn't marketing and it's very complete, I will comment on it step-by-step:
  1. he first %X converted in hexadecimal 49354 resulting C0CA (read "cê", "zero", "cê" and "a");
  2. Then came a blank space followed by another %XL. The %X converted 192 resulting in C0 it with L did C0L;
  3. And finally the last %X turned 10 in A.
 
Changed:
<
<
Conforme vocês podem notar, a instrução printf é bastante completa e complexa (ainda bem que o echo resolve quase tudo).
>
>
As you can see, the instruction printf it's fairly complete and complex (even though the echo solves almost everything).
 
Changed:
<
<
Creio que quando resolvi explicar o printf através de exemplos, acertei em cheio pois não saberia como enumerar tantas regrinhas sem tornar a leitura enfadonha.
>
>
I believe I did right when I decided to explain printf using examples, because I wouldn't know how to enumerate so many little rules without make for tedious reading.
 

Principais Variáveis do Shell

Revision 112 Mar 2014 - Main.AngelaFerreira

Line: 1 to 1
Added:
>
>
META TOPICPARENT name="WebHome"

Pub Talk Part IX



     - Okay, I know you will want to beer before you start, but I'm so anxious to show you what I did that I'm already asking to round up and then I'll show you.

     - Yo waiter, send two. His is no foam to not let this bad smell mustache ...

     - While the beer does not arrive let me remind you that you asked me to remake the listartist with formatted screen, in loop, so it only ends when you receive a pure <ENTER> on the name of artist. Possible error messages and questions should be given in the penultimate line of the screen using the routine sendmsg.func and question.func that just developed.

     - First I gave a shrunken in the sendmsg.func and question.func, which were as follows:

$ cat sendmsg.func # The function takes only one parameter # with the message that you want to display, # to not force the programmer to pass # the message in quotes, we'll use $* (all # parameters, remember?) and not $1. Msg="$*" TamMsg=${#Msg} Col=$(((TotCols - TamMsg) / 2)) # Centralizes message on row tput cup $LineMesg $Col read -n1 -p "$Msg "

$ cat question.func # The function takes 3 parameters in the following order: # $1 - Message to be given on the screen # $2 - Value to be accepted with default response # $3 - The other accepted value # Supposing that $1=Accept?, $2=y e $3=n, the row # then put the value in message "Accept? (Y/n)" Msg="$1 (`echo $2 | tr a-z A-Z`/`echo $3 | tr A-Z a-z`)" TamMsg=${#Msg} Col=$(((TotCols - TamMsg) / 2)) # Centralizes message on row tput cup $LineMesg $Col read -n1 -p "$Msg " SN [ ! $SN ] && SN=$2 # If empty puts default on SN SN=$(echo $SN | tr A-Z a-z) # The output of SN will be in lowercase tput cup $LineMesg $Col; tput el # Deletes the message screen

     - And now here's the big one:

$ cat listartista3 #!/bin/bash # Entered an artist, shows his musics # version 3

LineMesg=$((`tput lines` - 3)) # Line messages will be given to operator TotCols=$(tput cols) # Number of columns of screen to frame messages

clear echo " +----------------------------------------------------+  | List All Songs of a Particular Artist |  | ----- ----- -- ------- -- -- ----------- ------- |  | |  | Enter the Artist: | +----------------------------------------------------+" while true do tput cup 5 51; tput ech 31 # ech=Erase chars (31 characters to not erase vertical bar) read Name if [ ! "$Name" ] # $Is Name empty? then . question.func "Do you wish to finish?" y n [ $SN = n ] && continue break fi

fgrep -iq "^$Name~" musics || # fgrep not interpret ^ as regular expression { . sendmsg.func "There is no music of this artist" continue }

tput cup 7 29; echo '| |' LinAtual=8 IFS=" :" for ArtMus in $(cut -f2 -d^ musics) # Deletes album name do if echo "$ArtMus" | grep -iq "^$Name~" then tput cup $LinAtual 29 echo -n '| ' echo $ArtMus | cut -f2 -d~ tput cup $LinAtual 82 echo '|' let LinAtual++ if [ $LinAtual -eq $LineMesg ] then . sendmsg.func "Enter Something to Continue..." tput cup 7 0; tput ed # Erases the screen from row 7 tput cup 7 29; echo '| |' LinAtual=8 fi fi done tput cup $LinAtual 29; echo '| |' tput cup $((++LinAtual)) 29 read -n1 -p "+-----------Enter Something to New Query------------+" tput cup 7 0; tput ed # Erases the screen from row 7 done

     - Gosh, you got it all! But I liked the way you solved the problem and structured the program. It was more laborious but the presentation was very cool and you explored tput options. Let's test the result with an album Emerson, Lake & Palmer I have registered.

              +----------------------------------------------------+
              |  List All Songs of a Particular Artist  |
              |  ----- ----- -- ------- -- -- ----------- -------  |
              |                                                    |
              |  Enter the Artist: Emerson, Lake & Palmer         |
              +----------------------------------------------------+
              |                                                    |
              |  Jerusalem                                         |
              |  Toccata                                           |
              |  Still ... You Turn Me On                          |
              |  Benny The Bouncer                                 |
              |  Karn Evil 9                                       |
              |                                                    |
              +-----------Enter Something to New Query------------+

Improving writing

    - Ufa! Agora você já sabe tudo sobre leitura, mas sobre escrita está apenas engatinhando. Já sei que você vai me perguntar:
    - Ora, não é com o comando echo e com os redirecionamentos de saída que se escreve?

É, com estes comandos você escreve 90% das coisas necessárias, porém se precisar de escrever algo formatado eles lhe darão muito trabalho. Para formatar a saída veremos agora uma instrução muito interessante e que é de execução muito veloz, porque, assim como o echo, é um comando intrínseco (builtin) do Shell - é o printf - sua sintaxe é a seguinte:

    printf formato [argumento...]

Onde:
formato - é uma cadeia de caracteres que contem 3 tipos de objeto:

  1. caracteres simples;
  2. caracteres para especificação de formato;
  3. seqüência de escape no padrão da linguagem C.
Argumento - é a cadeia a ser impressa sob o controle do formato.

Cada um dos caracteres utilizados para especificação de formato é precedido pelo caracter % e logo a seguir vem a especificação de formato de acordo com a tabela:

Tabela dos Caracteres de Formatação do printf
%  Imprime um %. Não existe nenhuma conversão  
  Letra     A expressão será impressa como:
c  Simples caractere  
d  Número no sistema decimal  
e  Notação científica exponencial  
f  Número com ponto decimal (float)  
g O menor entre os formatos %e e %f com supressão dos zeros não significativos
o  Número no sistema octal  
s  Cadeia de caracteres  
x  Número no sistema hexadecimal  

As seqüências de escape padrão da linguagem C são sempre precedidas por um contra-barra (\) e as reconhecidas pelo comando printf são:

Sequencias de Escape do printf
t   Avança para a próxima marca de tabulação  
  Seqüência     Efeito  
a   Soa o beep  
b   Volta uma posição (backspace)  
f   Salta para a próxima página lógica (form feed)  
n   Salta para o início da linha seguinte (line feed)  
r   Volta para o início da linha corrente (carriage return)  

Não acabou por aí não! Tem muito mais coisa sobre a instrução, mas como é muito cheio de detalhes e, portanto, chato para explicar e, pior ainda para ler ou estudar, vamos passar direto aos exemplos com seus comentários, que não estou aqui para encher o saco de ninguém.

$ printf "%c" "1 caracter" 1$ Errado! Só listou 1 caractere e não saltou linha ao final $ printf "%c\n" "1 caracter" 1 Saltou linha mas ainda não listou a cadeia inteira $ printf "%c caractere\n" 1 1 caractere Esta é a forma correta o %c recebeu o 1 $ a=2 $ printf "%c caracteres\n" $a 2 caracteres O %c recebeu o valor da variável $a $ printf "%10c caracteres\n" $a          2 caracteres $ printf "%10c\n" $a caracteres          2 c

Repare que nos dois últimos exemplos, em virtude do %c, só foi listado um caracter de cada cadeia. O 10 à frente do c, não significa 10 caracteres. Um número seguindo o sinal de percentagem (%) significa o tamanho que a cadeia terá após a execução do comando.

E tome de exemplo:

$ printf "%d\n" 32 32 $ printf "%10d\n" 32 32 Preenche com brancos à esquerda e não com zeros $ printf "%04d\n" 32 0032 04 após % significa 4 dígitos com zeros à esquerda $ printf "%e\n" $(echo "scale=2 ; 100/6" | bc) 1.666000e+01 O default do %e é 6 decimais $ printf "%.2e\n" `echo "scale=2 ; 100/6" | bc` 1.67e+01 O .2 especificou duas decimais $ printf "%f\n" 32.3 32.300000 O default do %f é 6 decimais $ printf "%.2f\n" 32.3 32.30 O .2 especificou duas decimais $ printf "%.3f\n" `echo "scale=2 ; 100/6" | bc` 33.330 O bc devolveu 2 decimais. o printf colocou 0 à direita $ printf "%o\n" 10 12 Converteu o 10 para octal $ printf "%03o\n" 27 033 Assim a conversão fica com mais jeito de octal, né? $ printf "%s\n" Peteleca Peteleca $ printf "%15s\n" Peteleca Peteleca Peteleca com 15 caracteres enchidos com brancos $ printf "%-15sNeves\n" Peteleca Peteleca Neves O menos (-) encheu à direita com brancos $ printf "%.3s\n" Peteleca Pet 3 trunca as 3 primeiras $ printf "%10.3sa\n" Peteleca Peta Pet com 10 caracteres concatenado com a (após o s) $ printf "EXEMPLO %x\n" 45232 EXEMPLO b0b0 Transformou para hexa mas os zeros não combinam $ printf "EXEMPLO %X\n" 45232 EXEMPLO B0B0? Assim disfarçou melhor (repare o X maiúsculo) $ printf "%X %XL%X\n" 49354 192 10 C0CA? C0LA?

O último exemplo não é marketing e é bastante completo, vou comentá-lo passo-a-passo:

  1. O primeiro %X converteu 49354 em hexadecimal resultando C0CA (leia-se "cê", "zero", "cê" e "a");
  2. Em seguida veio um espaço em branco seguido por outro %XL. O %X converteu o 192 dando como resultado C0 que com o L fez C0L;
  3. E finalmente o último %X transformou o 10 em A.

Conforme vocês podem notar, a instrução printf é bastante completa e complexa (ainda bem que o echo resolve quase tudo).

Creio que quando resolvi explicar o printf através de exemplos, acertei em cheio pois não saberia como enumerar tantas regrinhas sem tornar a leitura enfadonha.

Principais Variáveis do Shell

O Bash possui diversas variáveis que servem para dar informações sobre o ambiente ou alterá-lo. Seu número é muito grande e não pretendo mostrar todas, mas uma pequena parte que pode lhe ajudar na elaboração de scripts. Então aí vão as principais:

Principais variáveis do Bash
TMOUT Se tiver um valor maior do que zero, este valor será tomado como o padrão de timeout do comando read. No prompt, este valor é interpretado como o tempo de espera por uma ação antes de expirar a sessão. Supondo que a variável contenha 30, o Shell dará logout após 30 segundos de prompt sem nenhuma ação.
      Variável Conteúdo
CDPATH Contém os caminhos que serão pesquisados para tentar localizar um diretório especificado. Apesar desta variável ser pouco conhecida, seu uso deve ser incentivado por poupar muito trabalho, principalmente em instalações com estrutura de diretórios com bastante níveis.
HISTSIZE Limita o número de instruções que cabem dentro do arquivo de histórico de comandos (normalmente .bash_history mas efetivamente é o que está armazenado na variável $HISTFILE). Seu valor default é 500.  
HOSTNAME O nome do host corrente (que também pode ser obtido com o comando uname -n).
LANG Usada para determinar a língua falada no pais (mais especificamente categoria do locale).
LINENO O número da linha do script ou da função que está sendo executada, seu uso principal é para dar mensagens de erro juntamente com as variáveis $0 (nome do programa) e $FUNCNAME (nome da função em execução)
LOGNAME Armazena o nome de login do usuário.
MAILCHECK Especifica, em segundos, a freqüência que o Shell verificará a presença de correspondências nos arquivos indicados pela variáveis $MAILPATH ou $MAIL. O tempo padrão é 60 segundos. Uma vez este tempo expirado, o Shell fará esta verificação antes de exibir o próximo prompt primário (definido em $PS1). Se esta variável estiver sem valor ou com um valor menor ou igual a zero, a verificação de novas correspondências não será efetuada.
PATH Caminhos que serão pesquisados para tentar localizar um arquivo especificado. Como cada script é um arquivo, caso use o diretório corrente (.) na sua variável $PATH, você não necessitará de usar o ./scrp para que scrp seja executado. Basta fazer scrp. Este é o modo que procedo aqui no Botequim.
PIPESTATUS É uma variável do tipo vetor (array) que contém uma lista valores de código de retorno do último pipeline executado, isto é, um array que abriga cada um dos $? de cada instrução do último pipeline.
PROMPT_COMMAND Se esta variável receber uma instrução, toda vez que você der um <ENTER> direto no prompt principal ($PS1), este comando será executado. É útil quando se está repetindo muito uma determinada instrução.
PS1 É o prompt principal. No "Papo de Botequim" usamos os seus defaults: $ para usuário comum e # para root, mas é muito freqüente que ele esteja customizado. Uma curiosidade é que existe até concurso de quem programa o $PS1 mais criativo. (clique para dar uma googlada)
PS2 Também chamado prompt de continuação, é aquele sinal de maior (>) que aparece após um <ENTER> sem o comando ter sido encerrado.
PWD Possui o caminho completo ($PATH) do diretório corrente. Tem o mesmo efeito do comando pwd.
RANDOM Cada vez que esta variável é acessada, devolve um número inteiro, que é um randômico entre 0 e 32767.
REPLY Use esta variável para recuperar o último campo lido, caso ele não tenha nenhuma variável associada.
SECONDS Esta variável contém a quantidade de segundos que o Shell corrente está de pé. Use-a somente para esnobar um usuários daquilo que chamam de sistema operacional, mas necessita de boots freqüentes. smile

  • CDPATH

$ echo $CDPATH .:..:~:/usr/local $ pwd /home/jneves/LM $ cd bin $ pwd /usr/local/bin

Como /usr/local estava na minha variável $CDPATH, e não existia o diretório bin em nenhum dos seus antecessores (., .. e ~), o cd foi executado para /usr/local/bin

  • LANG

$ date Thu Apr 14 11:54:13 BRT 2005 $ LANG=pt_BR date Qui Abr 14 11:55:14 BRT 2005

Com a especificação da variável LANG=pt_BR (português do Brasil), a data passou a ser informada no padrão brasileiro. É interessante observarmos que não foi usado ponto-e-vírgula (;) para separar a atribuição de LANG do comando date.

  • PIPESTATUS

$ who jneves pts/0 Apr 11 16:26 (10.2.4.144) jneves pts/1 Apr 12 12:04 (10.2.4.144) $ who | grep ^botelho $ echo ${PIPESTATUS[*]} 0 1

Neste exemplo mostramos que o usuário botelho não estava "logado", em seguida executamos um pipeline que procurava por ele. Usa-se a notação [*] em um array para listar todos os seus elementos, e desta forma vimos que a primeira instrução (who) foi bem sucedida (código de retorno 0) e a seguinte (grep), não (código de retorno 1).

  • RANDOM

Para gerar randomicamente um inteiro entre 0 e 100, fazemos:

$ echo $((RANDOM%101)) 73

Ou seja pegamos o resto da divisão por 101 do número randômico gerado, porque o resto da divisão de qualquer número por 101 varia entre 0 e 100.

  • REPLY

$ read -p "Digite S ou N: " Digite S ou N: N $ echo $REPLY N

Eu sou do tempo que memória era um bem precioso que custava muuuuito caro. Então para pegar um S ou um N, não costumo a alocar um espaço especial e assim sendo, pego o que foi digitado na variável $REPLY.

Expansão de parâmetros

Bem, muito do que vimos até agora são comandos externos ao Shell. Eles quebram o maior galho, facilitam a visualização, manutenção e depuração do código, mas não são tão eficientes quanto os intrínsecos (built-ins). Quando o nosso problema for performance, devemos dar preferência ao uso dos intrínsecos e a partir de agora vou te mostrar algumas técnicas para o teu programa pisar no acelerador.

Na tabela e exemplos a seguir, veremos uma série de construções chamadas expansão (ou substituição) de parâmetros (Parameter Expansion), que substituem instruções como o cut, o expr, o tr, o sed e outras de forma mais ágil.

Expansão de parâmetros
  ${cadeia~~}   Troca a caixa de todas as letra de cadeia (a partir do bash 4.0)
  Expressão   Resultado esperado
  ${var:-padrao}   Se var não tem valor, o resultado da expressão é padrao
  ${#cadeia}   Tamanho de $cadeia
  ${cadeia:posicao}   Extrai uma subcadeia de $cadeia a partir de posicao. Origem zero
  ${cadeia:posicao:tamanho}   Extrai uma subcadeia de $cadeia a partir de posicao com tamanho igual a tamanho. Origem zero
  ${cadeia#expr}   Corta a menor ocorrência de $cadeia à esquerda da expressão expr
  ${cadeia##expr}   Corta a maior ocorrência de $cadeia à esquerda da expressão expr
  ${cadeia%expr}   Corta a menor ocorrência de $cadeia à direita da expressão expr
  ${cadeia%%expr}   Corta a maior ocorrência de $cadeia à direita da expressão expr
  ${cadeia/subcad1/subcad2}   Troca em $cadeia a primeira ocorrência de subcad1 por subcad2
  ${cadeia//subcad1/subcad2}   Troca em $cadeia todas as ocorrências de subcad1 por subcad2
  ${cadeia/#subcad1/subcad2}   Se subcad1 combina com o início de $cadeia, então é trocado por subcad2
  ${cadeia/%subcad1/subcad2}   Se subcad1 combina com o fim de $cadeia, então é trocado por subcad2
  ${cadeia^}   Coloca a primeira letra de cadeia em maiúscula (a partir do bash 4.0)
  ${cadeia^^}   Coloca todas as letra de cadeia em maiúscula (a partir do bash 4.0)
  ${cadeia,}   Coloca a primeira letra de cadeia em minúscula (a partir do bash 4.0)
  ${cadeia,,}   Coloca todas as letra de cadeia em minúscula (a partir do bash 4.0)
  ${cadeia~}   Troca a caixa de cada primeira letra das palavras de cadeia (a partir do bash 4.0)

  • Se em uma pergunta o S é oferecido como valor default (padrão) e a saída vai para a variável $SN, após ler o valor podemos fazer:

    SN=${SN:-S}

Desta forma se o operador deu um simples <ENTER> para confirmar que aceitou o valor default, após executar esta instrução, a variável terá o valor S, caso contrário, terá o valor digitado.

  • Para sabermos o tamanho de uma cadeia:

$ cadeia=0123 $ echo ${#cadeia} 4

  • Para extrair de uma cadeia da posição um até o final fazemos:

$ cadeia=abcdef $ echo ${cadeia:1} bcdef

Repare que a origem é zero e não um.

  • Na mesma variável $cadeia do exemplo acima, para extrair 3 caracteres a partir da 2ª posição:

$ echo ${cadeia:2:3} cde

Repare que novamente que a origem da contagem é zero e não um.

  • Podemos também extrair do fim para o princípio

$ TimeBom=Flamengo $ echo ${TimeBom: -5} mengo $ echo ${TimeBom:(-5)} mengo

O espaço em branco ou os parênteses são obrigatórios para que o sinal de menos (-) não cole nos dois-pontos (:), que caso ocorresse, ficaria semelhante à expansão que vimos acima e que substitui uma variável vazia ou nula por um valor padrão (default), ou seja, a famosa ${var:-padrao}.

  • Para suprimir tudo à esquerda da primeira ocorrência de uma cadeia, faça:

$ cadeia="Papo de Botequim" $ echo ${cadeia#*' '} de Botequim $ echo "Conversa "${cadeia#*' '} Conversa de Botequim

Neste exemplo foi suprimido à esquerda tudo que casasse com a menor ocorrência da expressão *' ', ou seja, tudo até o primeiro espaço em branco.

Estes exemplos também poderiam ser escritos sem protegermos o espaço da interpretação do Shell (mas prefiro protegê-lo para facilitar a legibilidade do código), veja:

$ echo ${cadeia#* } de Botequim $ echo "Conversa "${cadeia#* } Conversa de Botequim

Repare que na construção de expr é permitido o uso de metacaracteres.

  • Utilizando o mesmo valor da variável $cadeia, observe como faríamos para termos somente Botequim:

$ echo ${cadeia##*' '} Botequim $ echo "Vamos 'Chopear' no "${cadeia##*' '} Vamos 'Chopear' no Botequim

Desta vez suprimimos à esquerda de cadeia a maior ocorrência da expressão expr. Assim como no caso anterior, o uso de metacaracteres é permitido.

Outro exemplo mais útil: para que não apareça o caminho (path) completo do seu programa (que, como já sabemos está contido na variável $0) em uma mensagem de erro, inicie o seu texto da seguinte forma:

    echo Uso: ${0##*/} texto da mensagem de erro

Neste exemplo seria suprimido à esquerda tudo até a última barra (/) do caminho (path), desta forma sobrando somente o nome do programa.

  • O uso do percentual (%) é como se olhássemos o jogo-da-velha (#) no espelho, isto é, são simétricos. Então vejamos um exemplo para provar isso:

$ echo $cadeia Papo de Botequim $ echo ${cadeia%' '*} Papo de $ echo ${cadeia%%' '*} Papo

  • Para trocar primeira ocorrência de uma subcadeia em uma cadeia por outra:

$ echo $cadeia Papo de Botequim $ echo ${cadeia/de/no} Papo no Botequim $ echo ${cadeia/de /} Papo Botequim

Neste caso preste a atenção quando for usar metacaracteres, eles são gulosos! Eles sempre combinarão com a maior possibilidade, veja o exemplo a seguir onde a intenção era trocar Papo de Botequim por Conversa de Botequim:

$ echo $cadeia Papo de Botequim $ echo ${cadeia/*o/Conversa} Conversatequim

A idéia era pegar tudo até o primeiro o, mas o que foi trocado foi tudo até o último o. Isto poderia ser resolvido de diversas maneiras, veja algumas:

$ echo ${cadeia/*po/Conversa} Conversa de Botequim $ echo ${cadeia/????/Conversa} Conversa de Botequim

  • Trocando todas as ocorrências de uma subcadeia por outra. Quando fazemos:

$ echo ${cadeia//o/a} Papa de Batequim

Trocamos todos as letras o por a. Veja agora um script para tirar espaços em branco dos nomes dos arquivos.

$ cat TiraBranco.sh #!/bin/bash # Renomeia arquivos com espaços nem branco #+ no nome, trocando-os por sublinhado (_). Erro=0 for Arq in *' '* do [ -f ${Arq// /_} ] && { echo $Arq não foi renomeado Erro=1 continue } mv "$Arq" "${Arq// /_}" done 2> /dev/null # Caso não exista arquivo com brancos o for dá erro exit $Erro

  • Trocando uma subcadeia no início ou no fim de uma variável. Para trocar no início fazemos:

$ echo $Passaro quero quero $ echo "Como diz o sulista - "${Passaro/#quero/não} Como diz o sulista - não quero

Para trocar no final fazemos:

$ echo "Como diz o nordestino - "${Passaro/%quero/não} Como diz o nordestino - quero não

Essas expansões foram introduzidas a partir do Bash 4.0 e modificam a caixa das letras do texto que está sendo expandido. Quando usamos circunflexo (^), a expansão é feita para maiúsculas, quando usamos vírgula (,), a expansão é feita para minúsculas e quando usamos til (~) a expansão troca a caixa das letras.

$ Nome="botelho" $ echo ${Nome^} Botelho $ echo ${Nome^^} BOTELHO $ Nome="botelho carvalho" $ echo ${Nome^} Botelho carvalho $ echo ${Nome~} # Capitalizando $Nome Botelho Carvalho $ Coisa="AAAbbb cccDDD" $ echo ${Coisa~} aAAbbb CccDDD $ echo ${Coisa~~} aaaBBB CCCddd

Um fragmento de script que pode facilitar a sua vida:

read -p "Deseja continuar (s/n)? "
[[ ${REPLY^} == N ]] && exit

Esta forma evita testarmos se a resposta dada foi um N (maiúsculo) ou um n (minúsculo).

No rWindows, além dos vírus e da instabilidade, também são frequentes nomes de arquivos com espaços em branco e quase todos em maiúsculas. Já vimos um exemplo de como trocar os espaços em branco por sublinha (_), no próximo veremos como passá-los para minúsculas (se você recebe muitos arquivos daquela coisa, o melhor é criar um script que seja a junção desses dois).

$ cat trocacase.sh #!/bin/bash # Se o nome do arquivo tiver pelo menos uma #+ letra maiúscula, troca-a para minúscula

for Arq in *[A-Z]* # Arquivos com pelo menos 1 minúscula do if [ -f "${Arq,,}" ] # Arq em minúsculas já existe? then echo ${Arq,,} já existe else mv "$Arq" "${Arq,,}" fi done

     - Agora já chega, o papo hoje foi muito chato porque foi muita decoreba, mas o principal é você ter entendido o que te falei e, quando precisar, consulte estes guardanapos em que rabisquei estas dicas e depois guarde-os para consultas futuras. Mas voltando à vaca fria: tá na hora de tomar outro e ver o jogo do mengão. Na próxima vou te dar moleza e só vou cobrar o seguinte: pegue a rotina pergunta.func, (a que na qual falamos no início do nosso bate papo de hoje) e otimize-a para que a variável $SN receba o valor default por expansão de parâmetros, como vimos.

     - Chico, vê se não esquece de mim e enche meu copo.

Vou aproveitar também para mandar o meu jabá: diga para os amigos que quem estiver afim de fazer um curso porreta de programação em Shell que mande um e-mail para a nossa gerencia de treinamento para informar-se.

Qualquer dúvida ou falta de companhia para um chope ou até para falar mal dos políticos é só mandar um e-mail para mim.

Valeu!

 
This site is powered by FoswikiCopyright © by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding Wiki-SL? Send feedback