msoliver
(usa Debian)
Enviado em 22/01/2020 - 20:51h
alex_tj escreveu:
msoliver escreveu:
alex_tj escreveu:
E aí galera, tudo beleza?
Queria a ajuda de vocês.... Estou fazendo um loop onde valido alguns logins que geralmente são compostos pelo CPF + '-' + Número Identificador de 4 dígitos (ex.: xxxxxxxxxxx-xxxx), qualquer coisa diferente disso eu tenho que jogar para um outro arquivo, mas ao mesmo tempo, tenho q deletar essas mesmas linhas do arquivo original.
Por exemplo:
"12345678912-1234","0.5","Curso: ABCD"
"09876543212-0258","1","Curso: XPTO"
"1234_4569","0.8","Curso" XPTO"
"36925801479-5236","0.9","Curso: FGHI"
"12358960785-XXXX","0.6","Curso: ABCD"
Sendo assim dessas linhas acima, as linhas 3 e 5 devem enviadas para outro arquivo e ao mesmo tempo deletadas, pois não estão dentro do padrão de login que tenho.
Sei que poderia fazer um sed dentro do while pra deletá-las porém esse processo para um arquivo de 17500 linhas demora mais de 10 minutos.
Aí que entra a ajuda, ao invés de fazer essa deleção linha a linha teria uma opção de armazenar essas linhas em uma variável e ao final do done deletar tudo de uma vez? Sabendo que a estrutura do sed para deleção de múltiplas linha é: sed '1d;5d;9d;$d' arq_teste.txt
Se tiver outra forma mais fácil aceito sugestões galera.
Veja como está meu código até o momento:
#!/bin/ksh
varSomenteNumero='^[0-9]+$'
n=1
while read -r line;
do IFS="|" read -a fld <<< "$line";
varLoginFuncionario=`echo "$line" | cut -d',' -f1 | sed 's/"//g' | sed 's/ //g' | cut -c1-16`
varLoginFuncionarioCount=`echo "$line" | cut -d',' -f1 | sed 's/"//g' | sed 's/ //g' | cut -c1-16 | awk '{print length}'`
varLoginFuncionarioParte1=`echo "$line" | cut -d',' -f1 | sed 's/"//g' | sed 's/ //g' | cut -c1-11`
varLoginFuncionarioParte2=`echo "$line" | cut -d',' -f1 | sed 's/"//g' | sed 's/ //g' | cut -c13-16`
varVerificaTraco=`echo "$line" | cut -d',' -f1 | sed 's/"//g' | sed 's/ //g' | cut -c1-16 | grep '-' | wc -l`
if ! [[ $varLoginFuncionarioParte1 =~ $varSomenteNumero ]] ||
! [[ $varLoginFuncionarioParte2 =~ $varSomenteNumero ]] ||
[ $varVerificaTraco -ne 1 ] ||
[ $varLoginFuncionarioCount -ne 16 ]; then
echo "O login:" $varLoginFuncionario "está fora do padrão estabelecido: CPF + '-' + Núm. Identificador (Ex.: xxxxxxxxxxx-xxxx)." >> ARQ_LOGINS_ERRO.TXT
sed -i "$n d" ARQ_CURSO.txt;
fi
: $((n++))
done < ARQ_CURSO.txt;
Desde já muito obrigado. Qualquer coisa tamu aew.
Abç.
Boa noite Alexandre.
Para "pegar" as linhas que não casam com o padrão, use o gawk.
Bem simples:
gawk -F"," '$1 !~ /\"[0-9]{11}-[0-9]{4}/ {printf "%sd;" ,NR}' texto_teste.txt
3d;5d;
Exemplo de uso:
Del_Lines=$(gawk '$1 !~ /\"[0-9]{11}-[0-9]{4}/ {printf "%sd;" ,NR}' texto_teste.txt);
sed -i "${Del_Lines}" texto_texte.txt
É isso.....
______________________________________________________________________
Importante: echo -e "\n$(lynx --dump goo.gl/a9KeFc|sed -nr '/^[ ]+Se/,/dou.$/p')\n"
Att.: Marcelo Oliver
______________________________________________________________________
Marcelo,
Boa tarde,
Esse comando de fato melhorou muito a performance do código porém pra mim ele está retornando todas as linhas independente de se encaixar no padrão ou não, pensei que talvez fosse por causa das aspas duplas ("), porém mesmo gerando um arquivo sem elas ele retorna todas as linhas.
Gerei um arquivo TESTE.tmp, com os valores exatamente como os abaixo:
"12345678912-1234","0.5","Curso: ABCD"
"1234567892-6589","0.2","Curso: ABCD"
"09876543212-0258","1","Curso: XPTO"
"1234_4569","0.8","Curso" XPTO"
"36925801479-5236","0.9","Curso: FGHI"
"1234567898-659","0.2","Curso: TESTE"
"12358960785-XXXX","0.6","Curso: ABCD"
"marques","1.0","Curso: AFGT"
Quando apliquei o comando: gawk -F"," '$1 !~ /\"[0-9]{11}-[0-9]{4}/ {printf "%sd;" ,NR}' TESTE.tmp
A resposta foi: 1d;2d;3d;4d;5d;6d;7d;8d;
Sendo que deveria ser: 2d;4d;6d;7d;8d;
Por isso ainda não entendi o que fiz de errado ao aplicar o comando.
Mas mto obrigado mesmo, cada contribuição tem me ajudado demais.
Boa noite Alex_tj.
Testei aqui novamente e funciona a contento.
Bem provável que o problema está ocorrendo, devido a falta do "gawk",
Para testar, removi o dito cujo, e listou todas linhas.....
O
gawk é necessário, devido a REGEX: /\"[0-9]{11}-[0-9]{4}/,
Sem ele, os quantificadores não são interpretados.....
which gawk
/usr/bin/gawk
awk '$1 !~ /\"[0-9]{11}-[0-9]{4}/ {printf "%s %s\n" ,NR,$0}' teste.txt
2 "1234567892-6589","0.2","Curso: ABCD"
4 "1234_4569","0.8","Curso" XPTO"
6 "1234567898-659","0.2","Curso: TESTE"
7 "12358960785-XXXX","0.6","Curso: ABCD"
8 "marques","1.0","Curso: AFGT"
OBS.:
Use somente a virgula como separador, se possível, elimine as " (aspas)
Tudo em uma linha:
Busca, deleta e gera o arquivo com os registros deletados
Faça um backup antes de usar.
Para testes, altere:
cmd="sed -i \"\x2f"$1".*\x2fd\" lista.txt"
Para:
cmd="sed -n \"\x2f"$1".*\x2fp\" lista.txt"
-i para -n e d para p
gawk -F"," '$1 !~ /[0-9]{11}-[0-9]{4}/ {cmd="sed -i \"\x2f"$1".*\x2fd\" lista.txt";system(cmd);print $0}' lista.txt >> reg_del.txt
Gerei um arquivo com 3000 linhas, alterei o padrão de 12 linhas,
Executei o comando e em 0,104s,
deletou as linhas e gerou o arquivo.
______________________________________________________________________
______________________________________________________________________
Importante: echo -e "\n$(lynx --dump goo.gl/a9KeFc|sed -nr '/^[ ]+Se/,/dou.$/p')\n"
Att.: Marcelo Oliver
______________________________________________________________________
______________________________________________________________________