shell-script-pt
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [shell-script] Substituir determinada posição


From: Adilson dos Reis
Subject: Re: [shell-script] Substituir determinada posição
Date: Wed, 10 Aug 2016 17:49:29 +0000 (UTC)

for n in $(cat arq.txt); do echo ${n:0:8}:${n:10:28}:${n:30:42}:${n:44:51}; done;


Em Quarta-feira, 10 de Agosto de 2016 14:10, "William Alves dos Santos address@hidden [shell-script]" <address@hidden> escreveu:


 
​Prezados,

O interpretador é o ksh, por compatibilidade com outros scripts que já foram desenvolvidos em korn shell em Tru64.

Na questão do sed, realizei um primeiro sed para inserir o caractere na posição especifica, e outro sed para remover a posição marcada mais o caractere irregular 'S', mas precisei utilizar um arquivo externo, contendo as instruções.

Caso alguém conheça uma maneira mais simples, favor informar.

Resolvi da seguinte forma:

#!/bin/ksh

#-----------------------------------------------------------------------------------------------
# VARIAVEIS DE AMBIENTE
#-----------------------------------------------------------------------------------------------

DIR_DATAIN="<DECLARAR _O_DIRETÓRIO_DA ENTRADA_DO_ARQUIVO>"
DIR_TMP="<DECLARAR_O_DIRETÓRIO_TEMPORÁRIO>"
ARQMARC="${DIR_DATAIN}/${1}" #PARM1: NOME_DO_ARQUIVO_DE_ENTRADA

#-----------------------------------------------------------------------------------------------
# REMOVER ARQUIVOS TEMPORÁRIOS, PARA EVITAR ERROS DE PROCESSAMENTO
#------------------------------------------------------------------------------------------------

rm -f ${DIR_TMP}/qtd_caractere_lin.$$.tmp
rm -f ${DIR_TMP}/lista_colunas_sep.$$.tmp
rm -f ${DIR_TMP}/replace.$$.tmp

#-----------------------------------------------------------------------------------------------
# VERIFICAR SE O ARQUIVO DE ENTRADA ESTA UNIFORME NA QUESTÃO DE QUANTIDADE DE COLUNAS E CAMPOS
#-----------------------------------------------------------------------------------------------

QTD_REG=`wc -l ${ARQMARC} | cut -f1 -d' '`
cat ${ARQMARC} | while read LIN; do
   echo $LIN | wc -m >> ${DIR_TMP}/qtd_caractere_lin.$$.tmp
done

VER_QTD=`sort ${DIR_TMP}/qtd_caractere_lin.$$.tmp | uniq -c | wc -l`

if [ $VER_QTD -eq 1 ]; then
   {
      echo "Quantidade de colunas uniforme no arquivo de entrada ."
      echo "Será possível realizar e encontrar os separadores de coluna ."
      VER_REG=`sort ${DIR_TMP}/qtd_caractere_lin.$$.tmp | uniq -c | awk '{print $2}'`
   }
else
   {
      echo "Não será possível encontrar os separadores de coluna ."
      echo "Deve ser realizado o alinhamento das colunas e espaços faltantes ."
      exit 0
   }
fi

#-----------------------------------------------------------------------------------------------
# ENCONTRAR AS COLUNAS - MARCADAS COM: "S" (Não vou nem comentar)
#-----------------------------------------------------------------------------------------------

CNT1=1
while [ $CNT1 -lt $VER_REG ]; do
   UNICO=`cat ${ARQMARC} | cut -c ${CNT1}-${CNT1} | sort -u | wc -l`
   if [ $UNICO -eq 1 ]; then
      {
         COL_S=`cat ${ARQMARC} | cut -c ${CNT1}-${CNT1} | sort -u`
         if [ $COL_S == 'S' ]; then
            {
               echo "SIM ESTA COLUNA É UNICA ${CNT1} ."
               echo $CNT1 >> ${DIR_TMP}/lista_colunas_sep.$$.tmp
            }
         fi
      }
   fi
   let CNT1=$CNT1+1
done

SEP=`cat ${DIR_TMP}/lista_colunas_sep.$$.tmp`
set -A SEP $SEP
QTD_COLUNAS=$(expr 1 + `echo ${#SEP[@]}`)
QTD_ELEMENT=`echo ${#SEP[@]}`

#-----------------------------------------------------------------------------------------------
# REPLACE: COLUNAS ENCONTRADAS COM: "S" POR "|"
#-----------------------------------------------------------------------------------------------

CNT0=0
while [ $CNT0 -lt $QTD_ELEMENT ]; do
   PNT=`echo ${SEP[$CNT0]}`
   echo '/^.\{'${PNT}',\}$/ { s/.\{'${PNT}'\}/&\|/};s/S|/|/' >> ${DIR_TMP}/replace.$$.tmp
   let CNT0=$CNT0+1
done

rm -f  ${DIR_TMP}/${ARQMARC}.$$.NEW
sed -f ${DIR_TMP}/replace.$$.tmp ${ARQMARC} >> ${DIR_TMP}/${ARQMARC}.$$.NEW

#-----------------------------------------------------------------------------------------------
# LIMPEZA ARQUIVOS
#-----------------------------------------------------------------------------------------------

rm -f ${DIR_TMP}/qtd_caractere_lin.$$.tmp
rm -f ${DIR_TMP}/lista_colunas_sep.$$.tmp
rm -f ${DIR_TMP}/replace.$$.tmp
#-----------------------------------------------------------------------------------------------
exit 0

FIM

Abraços

William Alves dos Santos
Cel.: +55 (11) 96835 8172


Em 10 de agosto de 2016 13:19, Tiago Peczenyj address@hidden [shell-script] <address@hidden> escreveu:
 
Ola

eu vejo algumas opções

awk com variavel FIELDWIDTHS onde vc especifica o tamanho de cada campo ( e ai cria campos pares de 1 caracter q sera o seu S para ignorar ). o man do awk fala melhor sobre esta variavel

pode especificar a variavel OFS pra escolher o separador

$ awk -v OFS="|" -v FIELDWIDTHS="8 1 19 1 13 1 8" '{ print $1,$3,$5, $7 }' example
12233455|ajjdhkfklmdkljedjjs| sjskdjjSantos|williams
12233455|ajjdhkfklmdkljedjjs| sjskdjjrantos|williams
12233455|ajjdhkfklmdkljedjjs| sjskdjjyantos|williams
aaz33455|ajjdhkfklmdkljedjjs| sjskdjjanytos|willis12

vc pode usar o cut para pegar apenas o campos que vc quer, sem o S e ai usar o awk ou sed para pegar as posições, algo como

$ cut -c 1-8,10-20,22-28 arquivo | ...

mas ele sozinho nao ajuda muito.


2016-08-07 4:25 GMT+02:00 address@hidden [shell-script] <address@hidden. br>:
 
Prezados,

Peço a gentileza em encontrar uma solução, para a questão.

Arquivo de entrada modelo:

12233455SajjdhkfklmdkljedjjsSs jskdjjSantosSwilliamsS
12233455SajjdhkfklmdkljedjjsSs jskdjjrantosSwilliamsS
12233455SajjdhkfklmdkljedjjsSs jskdjjyantosSwilliamsS
aaz33455SajjdhkfklmdkljedjjsSs jskdjjanytosSwillis12S


Por incrível que pareça colocaram o caractere 'S' maiusculo como separador, por este motivo um simples tr ou um sed não funcionária corretamente.

A primeira linha do exemplo consta um a string que possui o valor: "sjskdjjSantos", na terceira coluna.
 
A parte boa que tudo possui tamanho fixo, eu já consegui identificar as posições onde devo substituir, mas não consegui montar um sed que realize as substituições.

Poderia ser utilizado um laço para ler linha a linha cortando (substrings) e remontando as partes, mas o arquivo é muito grande e o tempo de processamento não será satisfátório.

Como realizar a substituição?

Somente dos campos: "9 29 43 52"

Obrigado



--
Tiago B. Peczenyj

http://about.me/peczenyj




reply via email to

[Prev in Thread] Current Thread [Next in Thread]