Usando o sed

Primeiramente vamos criar o arquivo p.c com o seguinte conteúdo:


#include <stdarg.h>

#include <stdio.h>

int IntSum(int TotalNumbers,...){

va_list numbers;

int TotalSum, counter;

va_start(numbers,TotalNumbers);

TotalSum = 0;

for(counter = 0; counter < TotalNumbers;counter++){

TotalSum+=va_arg(numbers,int);

}

va_end(numbers);

return TotalSum;

}

int main(){

printf("\n\t Soma Total 5 + 2 + 3 + 35 = %d",IntSum(4,5,2,3,35));

printf("\n\t Soma Total 10 + 2 = %d",IntSum(2,10,2));

return 1;

}

Imprimindo a primeira linha do arquivo:


eduardo@debian:~/Documents/regex$ sed '1!d' p.c

#include <stdarg.h>

Imprimindo a última linha do arquivo:


eduardo@debian:~/Documents/regex$ sed '$!d' p.c

}

Vamos exluir todas as linhas que compoem nossa função main:


eduardo@debian:~/Documents/regex$ sed '/int main/,/}/ d' p.c

#include <stdarg.h>

#include <stdio.h>

int IntSum(int TotalNumbers,...){

va_list numbers;

int TotalSum, counter;

va_start(numbers,TotalNumbers);

TotalSum = 0;

for(counter = 0; counter < TotalNumbers;counter++){

TotalSum+=va_arg(numbers,int);

}

va_end(numbers);

return TotalSum;

}

Agora, vamos exluir tudo que está dentro da nossa função main:


eduardo@debian:~/Documents/regex$ sed '/int main/,/}/ {/int main/ b; /}/ b; d}' p.c

#include <stdarg.h>

#include <stdio.h>

int IntSum(int TotalNumbers,...){

va_list numbers;

int TotalSum, counter;

va_start(numbers,TotalNumbers);

TotalSum = 0;

for(counter = 0; counter < TotalNumbers;counter++){

TotalSum+=va_arg(numbers,int);

}

va_end(numbers);

return TotalSum;

}

int main(){

}

Antes, excluímos a nossa função main do código, apenas como operador “!”, podemos fazer o contrário, ou seja, só vamos deixar a função main no código:

Obs: veja que é o mesmo comando que rodamos anteriormente, o que muda é o “!”.


eduardo@debian:~/Documents/regex$ sed '/int main/,/}/! d' p.c

int main(){

printf("\n\t Soma Total 5 + 2 + 3 + 35 = %d",IntSum(4,5,2,3,35));

printf("\n\t Soma Total 10 + 2 = %d",IntSum(2,10,2));

return 1;

}

Imagine que a nossa função main estivesse sem os tabs, como abaixo:


#include <stdarg.h>

#include <stdio.h>

int IntSum(int TotalNumbers,...){

va_list numbers;

int TotalSum, counter;

va_start(numbers,TotalNumbers);

TotalSum = 0;

for(counter = 0; counter < TotalNumbers;counter++){

TotalSum+=va_arg(numbers,int);

}

va_end(numbers);

return TotalSum;

}

int main(){

printf("\n\t Soma Total 5 + 2 + 3 + 35 = %d",IntSum(4,5,2,3,35));

printf("\n\t Soma Total 10 + 2 = %d",IntSum(2,10,2));

return 1;

}

Aqui, não vamos criar um novo arquivo, mas fica como um exemplo ilustrativo, se precisasse alterar, teríamos criar um outro arquivo:


eduardo@debian:~/Documents/regex$  sed '/int main/,/}/ {/int main/ b; /}/ b; s/^/\t/}' p.c

#include <stdarg.h>

#include <stdio.h>

int IntSum(int TotalNumbers,...){

va_list numbers;

int TotalSum, counter;

va_start(numbers,TotalNumbers);

TotalSum = 0;

for(counter = 0; counter < TotalNumbers;counter++){

TotalSum+=va_arg(numbers,int);

}

va_end(numbers);

return TotalSum;

}

int main(){

printf("\n\t Soma Total 5 + 2 + 3 + 35 = %d",IntSum(4,5,2,3,35));

printf("\n\t Soma Total 10 + 2 = %d",IntSum(2,10,2));

return 1;

}

Agora vamos exluir apenas a primeira linha que contém um “#”.


eduardo@debian:~/Documents/regex$ sed '0,/#/{ d; }' p.c

#include <stdio.h>

int IntSum(int TotalNumbers,...){

va_list numbers;

int TotalSum, counter;

va_start(numbers,TotalNumbers);

TotalSum = 0;

for(counter = 0; counter < TotalNumbers;counter++){

TotalSum+=va_arg(numbers,int);

}

va_end(numbers);

return TotalSum;

}

int main(){

printf("\n\t Soma Total 5 + 2 + 3 + 35 = %d",IntSum(4,5,2,3,35));

printf("\n\t Soma Total 10 + 2 = %d",IntSum(2,10,2));

return 1;

}

Imagine que você quer apegar a última linha do arquivo.


#include <stdarg.h>

#include <stdio.h>

int IntSum(int TotalNumbers,...){

va_list numbers;

int TotalSum, counter;

va_start(numbers,TotalNumbers);

TotalSum = 0;

for(counter = 0; counter < TotalNumbers;counter++){

TotalSum+=va_arg(numbers,int);

}

va_end(numbers);

return TotalSum;

}

int main(){

printf("\n\t Soma Total 5 + 2 + 3 + 35 = %d",IntSum(4,5,2,3,35));

printf("\n\t Soma Total 10 + 2 = %d",IntSum(2,10,2));

return 1;

}

//FIM

Vamos tirar aquele “FIM” dali … Vamos usar mais um recurso fora do sed que é o comando tac que vai ler o arquivo ao contrário


tac p.c | sed '0,/FIM/{d; }' | tac

#include <stdarg.h>

#include <stdio.h>

int IntSum(int TotalNumbers,...){

va_list numbers;

int TotalSum, counter;

va_start(numbers,TotalNumbers);

TotalSum = 0;

for(counter = 0; counter < TotalNumbers;counter++){

TotalSum+=va_arg(numbers,int);

}

va_end(numbers);

return TotalSum;

}

int main(){

printf("\n\t Soma Total 5 + 2 + 3 + 35 = %d",IntSum(4,5,2,3,35));

printf("\n\t Soma Total 10 + 2 = %d",IntSum(2,10,2));

return 1;

}

Vamos mudar um pouco nosso target

Data            Evento

01/02/2000      Teste1

03/05/2010      Teste2

03/05/2011      Teste3

01/02/2000      Teste4

03/05/2011      Teste5

03/12/2011      Teste6

11/03/2000      Teste7

03/05/2013      Teste8

04/05/2013      Teste9

01/03/2000      Teste10

03/05/2013      Teste11

03/05/2013      Teste12

01/03/2000      Teste13

03/05/2013      Teste14

Vamos listar apenas os que ocorreram em 01/02/2000

eduardo@debian:~/Documents/regex$ sed '/01\/02\/2000/! d' tabela
01/02/2000 Teste1
01/02/2000 Teste4

Veja que precisamos fazer a combinação “\/” para que o comando fique correto.  Pois o separador de datas é o mesmo que o delimitador. Podemos dizer ao sed que vamos usar outro delimitador, vamos usar a vírgula.

eduardo@debian:~/Documents/regex$ sed '\,01/02/2000,! d' tabela

01/02/2000         Teste1

01/02/2000         Teste4

Viram, o mesmo resultado.

Agora vamos colcocar um “_” em cada teste, ficando assim: Teste_1 …

eduardo@debian:~/Documents/regex$ sed 's/^\(.\{16\}\)/\1_/' tabela

Data                      Evento

01/02/2000         Teste_1

03/05/2010         Teste_2

03/05/2011         Teste_3

01/02/2000         Teste_4

03/05/2011         Teste_5

03/12/2011         Teste_6

11/03/2000         Teste_7

03/05/2013         Teste_8

04/05/2013         Teste_9

01/03/2000         Teste_10

03/05/2013         Teste_11

03/05/2013         Teste_12

01/03/2000         Teste_13
03/05/2013      Teste_14

Vamos colocar um fator pra melhorar nossa performance, vamos salvar essa alteração no nosso próprio arquivo:

eduardo@debian:~/Documents/regex$ sed -i 's/^\(.\{16\}\)/\1_/' tabela

eduardo@debian:~/Documents/regex$ cat tabela

Data                      Evento

01/02/2000         Teste_1

03/05/2010         Teste_2

03/05/2011         Teste_3

01/02/2000         Teste_4

03/05/2011         Teste_5

03/12/2011         Teste_6

11/03/2000         Teste_7

03/05/2013         Teste_8

04/05/2013         Teste_9

01/03/2000         Teste_10

03/05/2013         Teste_11

03/05/2013         Teste_12

01/03/2000         Teste_13
03/05/2013         Teste_14

Vamos fazer um script, para automatizar nosso trabalho:

#!/bin/sh

Data=$1

Arquivo=$2
sed "\,$Data,!d" $Arquivo

Resultado:

eduardo@debian:~/Documents/regex$ ./fdata.sh 01/02/2000 tabela

01/02/2000         Teste_1

01/02/2000         Teste_4

Deixe uma resposta