Script "apagador de linhas"
Por conta de um problema que tive na empresa onde trabalho, criei este script que pode ser útil para quem tiver um problema semelhante ou simplesmente para aqueles que querem aprender um pouco sobre shell script.
Parte 2: Destrinchando o código
#!/bin/sh
A primeira linha é fácil, acredito que todos estão familiarizados com ela, diz que desejamos utilizar o interpretador sh (link para o bash).
As linhas precedidas por "#" são comentários e não serão interpretadas.
TMP=${TMP:-/tmp}
Esta também é fácil. Caso a variável de ambiente "TMP" não esteja definida, seta a variável "local" TMP para "/tmp".
BKP=`echo $2 | sed -e 's/\...*$//'`
Esta é um pouco mais complicada! Utiliza expressões regulares com o programa "sed" para pegar só o nome do arquivo, retirando a extensão.
Ela merece mais explicações:
OK, os mais ligados diriam que eu poderia em vez de "//" colocar "/\.bkp/", mas como eu utilizo esta variável para outros propósitos, não o fiz.
WFILE=${TMP}/${BKP}$$
São variáveis que eu defino:
WFILE ("work file") é um arquivo temporário que é criado no diretório "tmp" (variável $TMP). Seu nome é composto da seguinte forma: [nome do arquivo sem extensão] + [PID do processo atual] ("PID" = "Process ID", já que o Linux é multi-usuário, não queremos que ocorram problemas de "colisões" e "dead locks" no nosso sistema. O pid é obtido com o caracter de controle "$$").
SCRPT=${TMP}/script$$
SCRPT ("script") é um script do sed que será criado "dinamicamente" contento as linhas que devem ser "apagadas". Segue os mesmos princípios da variável "WFILE".
if [ $# -lt 2 ]; then
echo "Usage $0 <lines> <data>"
exit 1
fi
Condição que verifica se o número de parâmetros digitados ("$#") é menor ("-lt" = less than = menos que) que dois, caso seja verdade, mostra uma mensagem ("echo") e sai do programa retornando ao shell 1 ("exit 1").
rm -f $SCRPT
Remove o script temporário (a opção "-f" serve para "silenciar" o rm, caso o arquivo não exista ele não retornará erro).
for y in `cat $1`; do
echo "${y}d" >> $SCRPT
done
Faz um "loop" inserindo cada linha do arquivo informado no parâmetro "$1" da linha de comando no arquivo definido na variável SCRPT.
As linhas digitadas no arquivos são inseridas no script da seguinte forma:
1d
5d
10d
11d
...
O "d" informa que a linha de numero X deve ser deletada.
cp $2 ${BKP}.bkp
Faz backup do arquivo original para um de mesmo nome com extensão ".bkp".
cat $2 | sed -f $SCRPT >> $WFILE
Executa o script criado anteriormente "canalizando" a saída do "sed" para o "Work File" ("WFILE").
cp $WFILE $2
Sobrescrever o arquivo original com o "Work File".
rm -f $WFILE
Remove o "Work File".
rm -f $SCRPT
Remove o Script sed criado dinamicamente.
A primeira linha é fácil, acredito que todos estão familiarizados com ela, diz que desejamos utilizar o interpretador sh (link para o bash).
As linhas precedidas por "#" são comentários e não serão interpretadas.
TMP=${TMP:-/tmp}
Esta também é fácil. Caso a variável de ambiente "TMP" não esteja definida, seta a variável "local" TMP para "/tmp".
BKP=`echo $2 | sed -e 's/\...*$//'`
Esta é um pouco mais complicada! Utiliza expressões regulares com o programa "sed" para pegar só o nome do arquivo, retirando a extensão.
Ela merece mais explicações:
- $2 é o segundo parâmetro passado por linha de comando para o parâmetro, utilizo o "pipe" ( | ) para "canalizar" a saída do comando "echo" para o "sed";
- A expressão 's/\...*$//' indica que eu desejo substituir ("s") qualquer coisa depois do ponto ("\...*") até o fim da linha ("$") por vazio ("//").
OK, os mais ligados diriam que eu poderia em vez de "//" colocar "/\.bkp/", mas como eu utilizo esta variável para outros propósitos, não o fiz.
WFILE=${TMP}/${BKP}$$
São variáveis que eu defino:
WFILE ("work file") é um arquivo temporário que é criado no diretório "tmp" (variável $TMP). Seu nome é composto da seguinte forma: [nome do arquivo sem extensão] + [PID do processo atual] ("PID" = "Process ID", já que o Linux é multi-usuário, não queremos que ocorram problemas de "colisões" e "dead locks" no nosso sistema. O pid é obtido com o caracter de controle "$$").
SCRPT=${TMP}/script$$
SCRPT ("script") é um script do sed que será criado "dinamicamente" contento as linhas que devem ser "apagadas". Segue os mesmos princípios da variável "WFILE".
if [ $# -lt 2 ]; then
echo "Usage $0 <lines> <data>"
exit 1
fi
Condição que verifica se o número de parâmetros digitados ("$#") é menor ("-lt" = less than = menos que) que dois, caso seja verdade, mostra uma mensagem ("echo") e sai do programa retornando ao shell 1 ("exit 1").
rm -f $SCRPT
Remove o script temporário (a opção "-f" serve para "silenciar" o rm, caso o arquivo não exista ele não retornará erro).
for y in `cat $1`; do
echo "${y}d" >> $SCRPT
done
Faz um "loop" inserindo cada linha do arquivo informado no parâmetro "$1" da linha de comando no arquivo definido na variável SCRPT.
As linhas digitadas no arquivos são inseridas no script da seguinte forma:
1d
5d
10d
11d
...
O "d" informa que a linha de numero X deve ser deletada.
cp $2 ${BKP}.bkp
Faz backup do arquivo original para um de mesmo nome com extensão ".bkp".
cat $2 | sed -f $SCRPT >> $WFILE
Executa o script criado anteriormente "canalizando" a saída do "sed" para o "Work File" ("WFILE").
cp $WFILE $2
Sobrescrever o arquivo original com o "Work File".
rm -f $WFILE
Remove o "Work File".
rm -f $SCRPT
Remove o Script sed criado dinamicamente.