Modelos de script com uso do for.
Aplicar comandos em todos arquivos do diretório corrente.
Segue alguns modelos para aplicar comandos em todos arquivos do diretório corrente.
Escolha a condição que melhor lhe atende, o script, executará os comandos uma vez para cada arquivo da condição que se encontrar dentro do diretório, neste exemplo abaixo, condição de pesquisa é (*.txt), sobre eles é executado um (echo $1), o resultado é mostrar todos os .txt do diretório corrente, funciona como um ls, veja os demais exemplos e modifique a seu modo.
#!/bin/bash for i in *.txt ; do #coloque aqui seus comandos echo $i done
Este exemplo não parece inútil, serve somente como exemplo de script, troque "echo $i" para a aplicação que deseja, segue alguns exemplos, converter todos os textos para o formato MSDOS bastou trocar "echo $i" por "unix2dos $i"
#!/bin/bash for i in *.txt ; do #coloque aqui seus comandos unix2dos $i done
Ler arquivo linha por linha, troque o echo pelo comando desejado, o exemplo abaixo quebra a linha nos espaços e acaba exibindo palavra por linha, isto ocorre porque o espaço ou TAB é o delimitador default, como não foi informado outro o delimitador o espaço serviu como quebra de linha, veja o exemplo posterior com a correção.
for i in `cat /tmp/arquivo.txt` do # seus comandos aqui echo $i done
Corrigindo o problema, alterando o delimitador para usar o final de linha, observe que altera o IFS para $'\n e no final volta o que era.
ORI_IFS=$IFS IFS=$'\n' for LINHA in $(cat /tmp/testez/comandos.txt); do # seus comandos aqui echo $LINHA done IFS=$ORI_IFS
O script acima exibe a linha completa mas elimina as linhas em branco, com while no script abaixo exibe a linha completa inclusive as linhas em branco como estão no arquivo.
while read LINHA ; do # seus comandos aqui echo $LINHA done < /tmp/testez/comandos.txt
Para exibir linha por linha de uma arquivo o cat faz isto,
cat /tmp/testez/comandos.txt
os scripts com for e while acima servem como modelo para incluir comandos em lugar do echo..
sed -n 1p /tmp/testez/comandos.txt
cat /tmp/testez/comandos.txt | awk '{ print $0}'
converter páginas do manual (man) para arquivos em html.
#!/bin/bash for i in *.gz ; do #coloque aqui seus comandos man ./$i | man2html -title man\ $i -topm 5 > $i.html done
No exemplo acima acrescenta requer o pacote man2html instalado, acrescenta .html no nome do arquivo, find.1.gz em html fica find.1.gz.html, a "gambi" do exemplo abaixo mantém somente a parte do nome antes do primeiro ponto, find.1.gz em html tem o nome find.html.
#!/bin/bash for i in *.gz ; do #coloque aqui seus comandos nome=`basename $i .1.gz` man ./$i | man2html -title man\ $nome -topm 5 > $nome.html done
Falhou em man2 porque tem páginas do man em man1, man2, man3 até man6, o exemplo acima não funcionou como desejado porque falha nos demais diretórios, a solução "gabi" abaixo pega somente a parte do nome que vem antes do primeiro ponto.
#!/bin/bash for i in *.gz ; do #coloque aqui seus comandos arqespac=`echo $i | sed 's:\.: :g'` nome=`echo $arqespac | awk '{print $1}'` echo $nome man ./$i | man2html -title man\ $nome -topm 5 > $nome.html done
Como pode notar nos exemplos acima, pode acrescentar linhas até obter o resultado desejado, pode tentar tudo em uma única linha ou usar script para realizar tarefas por parte, com arquivos grande pode tornar a tarefa demorada, tudo é questão de testar e procurar pela ferramenta mais apropriada.
Parte de um script de backup, veja script com mais detalhes nos tutoriais sobre backup. Em /backup/dirhome.txt tem a lista de diretórios, cada linha no formato /home/diretorio o script abaixo monta a linha de comando do tar nomeando o arquivo com homediretorio.meiodia.tar.gz, uma linha de comando para cada linha do arquivo, monta e executa uma por uma
for i in `cat /backup/dirhome.txt` do #coloque aqui seus comandos MVAR2=`echo $i | sed "s|/||g"` /bin/tar czf $MVAR2.meiodia.tar.gz $i done
Loop com for, executar uma sequencia de comandos nos arquivos listados em arqlista, não use ponto ou caracteres especiais no nome deste arquivo, execute o script dentro do diretório onde estão os arquivos a serem modificados, este script é uma versão simplificada para limpar arquivos com download de messagens da lista de shell-script no yahoo, são arquivos pequenos e não tive preocupação com velocidade e outros detalhes, somente remover cabeçalhos e rodapé dos textos, funciona!.
#!/bin/bash for i in $( cat arqlista );do # exibir o nome do arquivo sendo processado echo $i # apagar da linha 1 até a 22 sed -i '1,22d' "$i" # depois apaga a linha 2 e 3 sed -i '2,3d' "$i" # apagar todas as linhas que contem "As partes desta mensagem" sed -i '/As partes desta mensagem/Id' "$i" # apagar as ultimas 9 linhas sed -i -e :a -e '$d;N;2,9ba' -e 'P;D' "$i" done
Exibir o nome do arquivo sendo processado, acrescente esta linha
echo $i
Ela vai exibir o parametro que o sed deverá usar. Ou se preferir, modifique a linha de comando do sed para exibir o conteúdo que casa com a condição, por exemplo retirar o -i ou trocar "d" por "!p", ou "p" algo como:
sed '1,22d' "$i"
Executar o script, basta criar o arquivo acima, faça a correção dos comandos e condição para o teu uso, torne executável e execute
chmod 777 arqlista sh arqlista
Outra versão do script acima com redirecionamento da saida.
Versões mais antigas do sed não tem a opçõa -i, precisa redirecionar a saida para outro arquivo e depois renomear, também em casos de aplicar outros comandos que requer o redirecionamento, nunca esqueça da copia de segurança, preferencialmente para outro local, ou melhor, pratique na cópia. No exemplo abaixo é feita a copia no mesmo diretório, como se aplica o sed varias varias, então precisa fazer a copia e renomear em cada aplicação do sed.
#!/bin/bash for i in $( cat arqlista );do # exibir o nome do arquivo sendo processado echo $i # apagar da linha 1 até a 22 mv "$i" arqtemp sed '1,22d' arqtemp > "$i" rm arqtemp done
Uso do until é identico ao while, procure por until no manual (man bash)
Formato de uso until
until [ condição verdadeira ] ; do # comandos done
Exemplo de script com until, fique atento à condição.
#!/bin/bash i=5 until [ $i -le 0 ] ; do # seus comandos aqui. echo "numero do contador atual $i" i=$[$i-1] done
Veja também sobre uso de watch e tail, no tutorial sobre log tem exemplos.