Função busca de CEP para Shell

Olá galera.
Já faz alguns meses que eu estou escrevendo uma função para
procurar ceps (diretamente do site dos correios).
A função ficou meio longa, mas eu ainda prefiro não transformá-la
em script pq é muito prático tê-la no meu .bashrc e .zshrc

#cep dos correios
#por nome de rua ou cep
#ex: $ cep Avenida Paulista
#https://www.vivaolinux.com.br/topico/Sed-Awk-ER-Manipulacao-de-Textos-Strings/CEP-pela-Shell
cep()
{
	local cephelp c sem pvar pini pfim ceppipes

	cephelp="Puxar CEP dos Correios

	Não utilize acentos, número de casa/apto/lote/prédio ou
	abreviações.  Para forçar pesquisar por resultados seme-
	lhantes, use opção -s . Curl e iconv são necessários.

	Exemplos
		cep 07140-190
		cep Rua Higienopolis Guarulhos
		cep -s rua higienopolis"

	#set scale option
	while getopts hs c
	do
		case $c in
			h)  #ajuda?
			    echo "$cephelp"
			    return ;;
			s)  #resultados semelhantes?
			    echo 'Buscando por resultados semelhantes..' >&2
			    shift $(( OPTIND - 1 ))
			    sem=S ;;
		esac
	done
	shift $(( OPTIND - 1 ))

	#check arguments
	if [[ -z "$*" ]] 
	then
		echo "$cephelp" >&2
		return 1
	fi

	#retirar acentos e espaços em branco do input
	set -- $( iconv -f utf-8 -t ascii//translit <<< "$*" | tr \  + )
	
	#bucar resultados
	pvar=90 ;pini=1 ;pfim="$pvar"
	while curl -L -\# 'http://www.buscacep.correios.com.br/sistemas/buscacep/resultadoBuscaCepEndereco.cfm' \
		--data "relaxation=${*}&tipoCEP=ALL&semelhante=${sem:-N}&qtdrow=${pvar}&pagini=${pini}&pagfim=${pfim}" |
		iconv -f iso-8859-1 -t utf-8 | grep -aF CEP: |
		sed -e 's/<td>/&\t/g ;s/">/&\t/g ;s/<[^>]*>//g ;s/\r\r/  /g ;s/\r//g ;s/\s\s/\n/g ;s/&nbsp;//g ;s/://g' |
		sed -e ':a;N;s/\n\(.\)/ \1/;ta' -e 's/^\s\s*// ;/\[\s/d' |
		column -dts$'\t' -N1,2,3,4 -T1,2,3

		#get exit codes
		[[ "${PIPESTATUS[*]:-${pipestatus[*]}}" != *[1-9]* ]]
	do
		(( pini = pini + pvar ))
		(( pfim = pfim + pvar ))
		sleep 1.2  #evita throttle
	done

	#erros e tentar puxar resultados semelhantes
	if (( pini < pvar )) && [[ "$ceppipes" = *[1-9]* ]]
	then
		if [[ -n "$sem" ]]
		then
			echo 'Nenhum resultado' >&2
			return 1
		else
			cep -s "${@}"
		fi
	fi
}

#informações por número de cep
cep2()
{
	curl -sL "https://api.postmon.com.br/v1/cep/${1}" | jq
}
#https://postmon.com.br/
cep3()
{
	curl -sL "https://viacep.com.br/ws/${1}/json/" | jq
}
#https://viacep.com.br/
cep4()
{
	curl -sL "http://apps.widenet.com.br/busca-cep/api/cep/${1}.json" | jq
}
#https://widenet.com.br/busca-cep/api-de-consulta/

Mais funções de shell no meu github:

3 Curtidas

Os correios mudaram o site… Aqui vai uma nova função, agora precisa do pacote JQ também por que os dados vem em JSON. Testei um pouco só mas parece OK:

#cep dos correios
#por nome de rua ou cep
#ex: $ cep Avenida Paulista
cep()
{
	local d t cephelp pvar pini pfim
	cephelp="Puxar CEP dos Correios

	Não utilize acentos, número de casa/apto/lote/prédio ou
	abreviações.

	Exemplos
		cep 07140-190
		cep Rua Higienopolis Guarulhos"

	#check arguments or -h opt
	if [[ -z "$1" ]] || [[ "$1" = -h ]]
	then
		echo "$cephelp"
		return 0
	fi

	#retirar espaços em branco e acentos do input
	set -- $( iconv -f utf-8 -t ascii//translit <<< "$*" | tr \  + )
	
	#bucar resultados
	pvar=50 ;pini=1 ;pfim="$pvar"
	while d="$( curl -L -\# "https://buscacepinter.correios.com.br/app/endereco/carrega-cep-endereco.php?pagina=%2Fapp%2Fendereco%2Findex.php&cepaux=&mensagem_alerta=&endereco=${*}&tipoCEP=ALL&inicio=${pini}&final=${pfim}" | jq -e . 2>/dev/null )"

		#check exit codes
		if [[ "${PIPESTATUS[*]:-${pipestatus[*]}}" = *[1-9]* ]]
		then
			return 1
		fi

		#error message in json?
		if [[ "$(jq -r .erro <<<"$d" )" != false ]]
		then
			jq -r .mensagem <<<"$d" >&2
			return 1
		fi
	do
		t="$(jq -r .total <<<"$d")"
		(( pini = pini + pvar ))
		(( pfim = pfim + pvar ))

		jq -r '.dados[] | "\(.cep)\t\(.uf)\t\(.localidade)\t\(.bairro)\t\(.logradouroDNEC)\t\(.numeroLocalidade)\t\(.logradouroTextoAdicional)\t\(.nomeUnidade)\t\(.situacao)"' <<<"$d"
		#column -dts$'\t' -N1,2,3,4,5,6,7,8,9 -T4,7,8,9
		#sleep 1.2  #evita throttle

		if (( pfim > t ))
		then
			jq -r .mensagem <<<"$d" | grep -vi sucesso && return 1
			return 0
		fi
	done
}

Alternativamente, fazer download de bancos de dados de CEP:

Manda uns prints funcionando ou então faz um vídeo no YouTube.

Lembrando que este exemplo genérico da Avenida Paulista tem um mooonte de resultados e resultados similares, e não cabe em um print.

Opcionalmente vcs podem adicionar um comando de ‘column’ para tabular os dados em uma tabela formatada. Na verdade, só por um pipe e ‘descomentar’ a linha que já tem um comando de column lá na função…