Tag Archives: unix

Unix: Como substituir letra maiúscula por minúscula em um arquivo

Para converter letras maiúsculas em letras minúsculas em um arquivo em sistemas Unix, pode-se usar o comando tr com a sintaxe a seguir:

tr '[:upper:]' '[:lower:]' < [arquivo] > [novoarquivo]

O comando tr pode ser usado para diversas outras manipulações de caracteres. Para mais informações consulte a man page do comando: man tr

O link a seguir tem mais informa̵̤es sobre o comando tr no AIX 7: AIX 7 РHelp Information РCommands Рtr

 

Email no Unix (mail/mailx) – Como enviar arquivo anexo

Como fazer para enviar um arquivo anexo através do comando mail ou mailx no Unix?

Por exemplo, pode ser necessário enviar um arquivo anexo em emails enviados através de scripts que realizam funções administrativas. Além do anexo, podemos enviar junto o conteúdo no corpo do email (body).

Seguem os passos para enviar um email contendo um arquivo compactado (.zip) e conteúdo no corpo do email:

1 – Compactar arquivos, gerando arquivo zip:

/usr/bin/zip arquivo.zip $diretorio/*ERR*

2 – Gerar o anexo. Para isso usamos o comando uuencode:

 /usr/bin/uuencode arquivo.zip arquivo.zip > attachment.txt

OBS: Sim, o nome do arquivo zip é repetido 2 vezes no comando. Não é erro de digitação. 🙂

3 – Combinar o anexo com o texto que irá no corpo do email:

cat texto_email.txt attachment.txt > combinado.txt

O arquivo texto_email.txt contém o que irá escrito no corpo do email.

4 -Enviar o email com conteúdo no corpo do email e arquivo zip anexo:

/usr/bin/mailx -s "Email com anexo e conteúdo" [email protected] < combinado.txt

A opção “-s” é para colocar o Assunto/Subject do email.

Incrementar variável numérica em bash2

Até a bash 1, para você incrementar uma variável numérica de 1 em 1 era preciso toda uma contorção:

contador=0; \
while [ $contador -lt 10 ]; \
do echo "o valor do contador eh $contador"; \
let contador=$contador+1; \
done

Agora, com a bash2, você pode usar o for de maneira parecida com a sintaxe do C:

for (( contador=0; contador < 10; contador++ )); \
do echo "o valor do contador eh $contador" ;\
done

bash: Argument list too long

Pode ser que você já tenha tentado dar um comando usando o asterisco * na bash e tenha obtido este erro:

bash: comando: Argument list too long

Aonde comando pode ser um rm, ou um cp, ou qualquer outro. Por exemplo:

[email protected]:~/teste$ rm -f *
bash: /bin/rm: Argument list too long
[email protected]:~/teste$

Quem imprimiu esse erro não foi o comando (o rm, no exemplo), mas a bash, que é responsável por expandir o wildcard *, substituindo-o pela lista de arquivos no diretório. Em sistemas UNIX, há um limite fixo de memória reservado para o ambiente e lista de parâmetros de um comando. No caso do meu servidor Linux, esse limite é 128K, mas isso varia de sistema para sistema. Você pode descobrir no seu sistema usando o comando getconf. Veja:

[email protected]:~/teste$ getconf ARG_MAX
131072
[email protected]:~/teste$

Agora, ao que interessa. Como fazer para remover os arquivos do meu exemplo acima? Existem diversas saídas, variando a eficiência dependendo de qual é o seu comando, na verdade. Mas vamos ver o rm, pois o exemplo dele pode ser aplicado a outros, como por exemplo o cp, ou o mv.

Se você puder eliminar o diretório inteiro no qual estão os arquivos, não há problemas:

[email protected]:~$ rm -rf teste/
[email protected]:~$

Se você só pode eliminar os arquivos, uma saída é usar o comando find.

[email protected]:~/teste$ find . -type f -exec rm -f {} \;
[email protected]:~/teste$

Nesse caso, eu pedi para o find encontrar no diretório em que estou (.) todos os arquivos (-type f) e para cada um deles executar (-exec) o comando rm. As chaves {} são substituídas por cada arquivo encontrado pelo find. Dessa forma o rm é executado uma vez para cada arquivo, tendo assim apenas aquele arquivo como parâmetro, o que evita ultrapassar o limite de memória imposto. O final \; é para fechar o comando do -exec com um ponto e vírgula, que precisa ser precedido da contra barra (\) para que a bash não o interprete (uma vez que ; é um caractere com sentido especial para a bash) e apenas o passe para o find.

Caso, por exemplo, você precise remover somente os arquivos html e não os arquivos .php em um diretório, basta usar o find novamente:

[email protected]:~/teste$ ls *.php
1.php  2.php
[email protected]:~/teste$ ls
(saida resumida:)
23497.html  36998.html  50498.html  6399.html   774.html    9.html
23498.html  36999.html  50499.html  639.html    77500.html
23499.html  3699.html   5049.html   63.html     77501.html
2349.html   369.html    504.html    64000.html  77502.html
234.html    36.html     50500.html  64001.html  77503.html

[email protected]:~/teste$ find . -name \*.html -exec rm -f {} \;
[email protected]:~/teste$ ls
1.php  2.php
[email protected]:~/lixo

Aqui o asterisco funciona porque está precedido pela contrabarra o que faz com que a bash não o interprete, apenas o find. E find não expande o asterisco em todos os arquivos do diretório, como a bash. Para o find, o asterisco é parte de uma expressão regular, que quer dizer “encontre arquivos cujo nome seja qualquer coisa seguida de um .html”.

Eu uso a versão da GNU do find, presente na maioria dos sistemas Linux. Caso o seu find não entenda o parâmetro -exec, use-o em conjunto com comando xargs:

[email protected]:~/teste$ find . -name \*.html | xargs rm -f
[email protected]:~/teste$ ls
1.php  2.php
[email protected]:~/teste$

Referências:

http://www.gnu.org/software/coreutils/faq/coreutils-faq.html#Argument-list-too-long

Uso interessante do awk РOp̤̣o system

O awk é uma ferramenta muito poderosa e tenho consciência que não uso 1/1000 do que ela oferece.

Descobri um uso interessante da ferramenta, que é a utilização da opção system que já premite executar diretamente o comando utilizando o campo selecionado.

Ex:

O comando lsvgfs lista os filesystems do VG:

# lsvgfs rootvg
/
/usr
/var
/tmp
/home
/opt

Utilizando o awk com a opção system, podemos por exemplo, desmontar os filesystems chamando o comando umount dentro do awk, fazendo tudo numa única linha de comando:

# lsvgfs rootvg | awk '{system("umount "$1)}'

 

Referência

Para saber mais sobre awk:

  1. http://www.gnu.org/software/gawk/
  2. http://en.wikipedia.org/wiki/AWK_%28programming_language%29

Concatenando arquivos na horizontal

Quando falamos em concatenar arquivos, sempre nos lembramos do comando cat, que concatena os arquivos verticalmente, colocando o conteúdo sequencialmente um abaixo do outro.

E se queremos colocar o conteúdo dos arquivos um ao lado do outro, concatenando horizontalmente?

Para isso, o unix tem o comando paste.

# paste  

Para saber mais sobre os comandos citados cheque a man page:

# man cat
# man paste

 

Referência

Online man pages:

  1. Comando paste
  2. Comando cat