|
From: | Itamar Santos de Souza |
Subject: | Re: [shell-script-pt] Digest shell-script-pt, volume 11, assunto 6 |
Date: | Thu, 12 Nov 2020 09:20:15 +0000 (UTC) |
Enviar submissões para a lista de discussão shell-script-pt para
shell-script-pt@nongnu.org
Para se cadastrar ou descadastrar via WWW, visite o endereço
https://lists.nongnu.org/mailman/listinfo/shell-script-pt
ou, via email, envie uma mensagem com a palavra 'help' no assunto ou
corpo da mensagem para
shell-script-pt-request@nongnu.org
Você poderá entrar em contato com a pessoa que gerencia a lista pelo
endereço
shell-script-pt-owner@nongnu.org
Quando responder, por favor edite sua linha Assunto assim ela será
mais específica que "Re: Contents of shell-script-pt digest..."
Tópicos de Hoje:
1. Re: Como iterar um array recursivo sem redundância? (Arkanon)
----------------------------------------------------------------------
Message: 1
Date: Wed, 11 Nov 2020 22:25:46 -0300
From: Arkanon <arkanon@lsd.org.br>
To: Lista brasileira de usuários de shell script
<shell-script-pt@nongnu.org>
Subject: Re: [shell-script-pt] Como iterar um array recursivo sem
redundância?
Message-ID:
<CALB+K0NEnN=ypZCZdsnqg+b7w_FtvdSEoB2h0kYY81TvXATSfw@mail.gmail.com>
Content-Type: text/plain; charset="utf-8"
Oi, Vilmar.
Em resumo, você quer uma forma de, de toda a listagem de pacotes, obter
apenas uma linha de cada grupo de linhas de pacote, contendo a versão mais
nova de cada pacote?
Se a listagem for fiel ao padrão rígido que parece seguir a amostra que
você nos passou, uma forma bastante simples de atingir esse objetivo seria,
por ex:
$ cat pacotes.txt
/var/cache/fetch/archives/nano-5.2-1-x86_64.chi.zst
/var/cache/fetch/archives/python-3.5.0-1-x86_64.chi.zst
/var/cache/fetch/archives/python-3.8.6-2-x86_64.chi.zst
/var/cache/fetch/archives/nano-5.3-1-x86_64.chi.zst
/var/cache/fetch/archives/python-3.8.6-1-x86_64.chi.zst
/var/cache/fetch/archives/nano-5.0-1-x86_64.chi.zst
$ sort -Vr pacotes.txt | sort -t- -k1,1 -u
/var/cache/fetch/archives/nano-5.3-1-x86_64.chi.zst
/var/cache/fetch/archives/python-3.8.6-2-x86_64.chi.zst
Talvez seja possível fazer isso com apenas um sort.
Att,
Em qua., 11 de nov. de 2020 às 20:24, Vilmar Catafesta <vcatafesta@gmail.com>
escreveu:
> Olá shelleiros, saudações
>
> Tenho em determinado diretório, milhares de arquivos de pacote de
> software, que por sua vez tem versões, como por exemplo:
>
> /var/cache/fetch/archives/python-3.5.0-1-x86_64.chi.zst
> /var/cache/fetch/archives/python-3.8.6-1-x86_64.chi.zst
> /var/cache/fetch/archives/python-3.8.6-2-x86_64.chi.zst
> /var/cache/fetch/archives/nano-5.0-1-x86_64.chi.zst
> /var/cache/fetch/archives/nano-5.2-1-x86_64.chi.zst
> /var/cache/fetch/archives/nano-5.3-1-x86_64.chi.zst
>
> A cada nova versão, necessito compilar e empacotar os mesmos, removendo as
> versão mais antigas do diretório, o qual escrevi esse script abaixo para a
> função de remover as versões mais antigas, deixando somente a versão mais
> atual.
>
> #!/usr/bin/bash
>
> aPKGSPLIT=()
> cachedirs=("/var/cache/fetch/archives")
> pkg_ext='.chi.zst'
> pkg_re='(.+)-(([^-]+)-([0-9]+))-([^.]+)\.chi\.zst'
> : ${aPKGSPLIT=()}
> : ${aPKGLIST=}
> : ${PKG_FOLDER_DIR=0}
> : ${PKG_FULLNAME=1}
> : ${PKG_ARCH=2}
> : ${PKG_BASE=3}
> : ${PKG_BASE_VERSION=4}
> : ${PKG_VERSION=5}
> : ${PKG_BUILD=6}
> function die(){
> local msg=$1; shift
> printf "%s %s\n" "$msg" "$@" >&2
> exit 1
> }
> sh_splitpkg(){
> local file=${1}
> local pkg_folder_dir=$(echo ${file%/*})
> local pkg_fullname=$(echo ${file##*/})
> local pkg_base=
> local pkg_version_build=
> local pkg_version=
> local pkg_build=
> local pkg_arch=
> local pkg_base_version=
>
> [[ $pkg_fullname =~ $pkg_re ]] &&
> pkg_fullname=${BASH_REMATCH[0]}
> pkg_base=${BASH_REMATCH[1]}
> pkg_version_build=${BASH_REMATCH[2]}
> pkg_version=${BASH_REMATCH[3]}
> pkg_build=${BASH_REMATCH[4]}
> pkg_arch=${BASH_REMATCH[5]}
> pkg_base_version=${pkg_base}-${pkg_version_build}
>
> aPKGSPLIT=($pkg_folder_dir $pkg_fullname $pkg_arch $pkg_base $pkg_base_version $pkg_version $pkg_build)
> return $?
> }
> main(){
> local pkg=
> local pkgInAll=
> local pkg_base=
> local pkg_search=
> local candidates=()
> local cachedir
>
> for cachedir in "${cachedirs[@]}"
> do
> [[ -d $cachedir ]] || die "Error: cachedir '$cachedir' does not exist or is not a directory"
> pushd "$cachedir" &>/dev/null || die "Error: failed to chdir to $cachedir"
>
> while read -r pkgInAll;do
> sh_splitpkg ${pkgInAll}
> pkg_base=${aPKGSPLIT[$PKG_BASE]}
>
> [[ -z "$pkg_base" ]] && continue
>
> while read -r pkg;do
> sh_splitpkg ${pkg}
> pkg_search=${aPKGSPLIT[$PKG_BASE]}
>
> [[ -z "$pkg_search" ]] && continue
> [[ "${pkg_search::1}" > "${pkg_base::1}" ]] && break
>
> if [[ "${pkg_base}" =~ "${pkg_search}" ]] && [[ "$(vercmp $pkgInAll $pkg)" -lt 0 ]]; then
> printf "%s\n" "${pkgInAll}"
> candidates+=("${pkgInAll}")
> fi
> done < <(printf '%s\n' "$(find "$PWD" -type f -name "$pkg_base*.zst" | grep -E "*$pkg_base-([0-9])" | sort)")
> done < <(printf '%s\n' "$(find "$PWD" -type f -name "*.chi.zst" | sort)")
> popd >/dev/null 2>&1
> done
>
> Tenho em determinado diretório, milhares de arquivos de pacote de software, que por sua vez tem versões, como por exemplo:
>
> /var/cache/fetch/archives/python-3.5.0-1-x86_64.chi.zst
> /var/cache/fetch/archives/python-3.8.6-1-x86_64.chi.zst
> /var/cache/fetch/archives/python-3.8.6-2-x86_64.chi.zst
> /var/cache/fetch/archives/nano-5.0-1-x86_64.chi.zst
> /var/cache/fetch/archives/nano-5.2-1-x86_64.chi.zst
> /var/cache/fetch/archives/nano-5.3-1-x86_64.chi.zst
>
> A cada nova versão, necessito compilar e empacotar os mesmos, removendo as
> versão mais antigas do diretório, o qual escrevi esse script abaixo para a
> função de remover as versões mais antigas, deixando somente a versão mais
> atual.
>
> #!/usr/bin/bash
>
> aPKGSPLIT=()
> cachedirs=("/var/cache/fetch/archives")
> pkg_ext='.chi.zst'
> pkg_re='(.+)-(([^-]+)-([0-9]+))-([^.]+)\.chi\.zst'
> : ${aPKGSPLIT=()}
> : ${aPKGLIST=}
> : ${PKG_FOLDER_DIR=0}
> : ${PKG_FULLNAME=1}
> : ${PKG_ARCH=2}
> : ${PKG_BASE=3}
> : ${PKG_BASE_VERSION=4}
> : ${PKG_VERSION=5}
> : ${PKG_BUILD=6}
> function die(){
> local msg=$1; shift
> printf "%s %s\n" "$msg" "$@" >&2
> exit 1
> }
> sh_splitpkg(){
> local file=${1}
> local pkg_folder_dir=$(echo ${file%/*})
> local pkg_fullname=$(echo ${file##*/})
> local pkg_base=
> local pkg_version_build=
> local pkg_version=
> local pkg_build=
> local pkg_arch=
> local pkg_base_version=
>
> [[ $pkg_fullname =~ $pkg_re ]] &&
> pkg_fullname=${BASH_REMATCH[0]}
> pkg_base=${BASH_REMATCH[1]}
> pkg_version_build=${BASH_REMATCH[2]}
> pkg_version=${BASH_REMATCH[3]}
> pkg_build=${BASH_REMATCH[4]}
> pkg_arch=${BASH_REMATCH[5]}
> pkg_base_version=${pkg_base}-${pkg_version_build}
>
> aPKGSPLIT=($pkg_folder_dir $pkg_fullname $pkg_arch $pkg_base $pkg_base_version $pkg_version $pkg_build)
> return $?
> }
> main(){
> local pkg=
> local pkgInAll=
> local pkg_base=
> local pkg_search=
> local candidates=()
> local cachedir
>
> for cachedir in "${cachedirs[@]}"
> do
> [[ -d $cachedir ]] || die "Error: cachedir '$cachedir' does not exist or is not a directory"
> pushd "$cachedir" &>/dev/null || die "Error: failed to chdir to $cachedir"
>
> while read -r pkgInAll;do
> sh_splitpkg ${pkgInAll}
> pkg_base=${aPKGSPLIT[$PKG_BASE]}
>
> [[ -z "$pkg_base" ]] && continue
>
> while read -r pkg;do
> sh_splitpkg ${pkg}
> pkg_search=${aPKGSPLIT[$PKG_BASE]}
>
> [[ -z "$pkg_search" ]] && continue
> [[ "${pkg_search::1}" > "${pkg_base::1}" ]] && break
>
> if [[ "${pkg_base}" =~ "${pkg_search}" ]] && [[ "$(vercmp $pkgInAll $pkg)" -lt 0 ]]; then
> printf "%s\n" "${pkgInAll}"
> candidates+=("${pkgInAll}")
> fi
> done < <(printf '%s\n' "$(find "$PWD" -type f -name "$pkg_base*.zst" | grep -E "*$pkg_base-([0-9])" | sort)")
> done < <(printf '%s\n' "$(find "$PWD" -type f -name "*.chi.zst" | sort)")
> popd >/dev/null 2>&1
> done
>
> if (( ! ${#candidates[*]} )); then
> die "NO packages found for pruning"
> fi
> }
>
> main $*
>
> O script cumpre bem a tarefa, pecando somente na questão de rapidez, sendo
> que são milhares de pacotes a processar, pois necessário verificar
> individualmente cada um deles com outro pacote para saber qual versão é
> mais atual.
>
> Alguma ideia para melhorar a rapidez dessa busca?
>
> nessa parte do código foi usado o find, pois os pacotes também se
> encontram em subdiretórios:
>
> done < <(printf '%s\n' "$(find "$PWD" -type f -name "*.chi.zst" | sort)")
>
> O cerne da questão é de como melhorar esse processamento abaixo:
>
> while read -r pkgInAll;do
> sh_splitpkg ${pkgInAll}
> pkg_base=${aPKGSPLIT[$PKG_BASE]}
>
> [[ -z "$pkg_base" ]] && continue
>
> while read -r pkg;do
> sh_splitpkg ${pkg}
> pkg_search=${aPKGSPLIT[$PKG_BASE]}
>
> [[ -z "$pkg_search" ]] && continue
> [[ "${pkg_search::1}" > "${pkg_base::1}" ]] && break
>
> if [[ "${pkg_base}" =~ "${pkg_search}" ]] && [[ "$(vercmp $pkgInAll $pkg)" -lt 0 ]]; then
> printf "%s\n" "${pkgInAll}"
> candidates+=("${pkgInAll}")
> fi
> done < <(printf '%s\n' "$(find "$PWD" -type f -name "$pkg_base*.zst" | grep -E "*$pkg_base-([0-9])" | sort)")
> done < <(printf '%s\n' "$(find "$PWD" -type f -name "*.chi.zst" | sort)")
>
>
> _______________________________________________
> Lista brasileira de usuários de shell script
> Endereço de e-mail da lista: shell-script-pt@nongnu.org
> Para se inscrever ou desinscrever acesse:
> https://lists.nongnu.org/mailman/listinfo/shell-script-pt
> Para ver os arquivos da lista (mensagens anteriores) e pesquisar nelas,
> acesse https://lists.nongnu.org/archive/html/shell-script-pt/
>
> NOTA: A lista anterior, no Yahoo Groups, foi *desativada*. Por favor
> utilize somente esta.
--
(o_ @arkanon <http://twitter.com/arkanon> (Twitter) __o
//\ arkanon@lsd.org.br _`\<,
V_/_ www.lsd.org.br (_)/(_)
---------------------------------
-------------- Próxima Parte ----------
Um anexo em HTML foi limpo...
URL: <https://lists.nongnu.org/archive/html/shell-script-pt/attachments/20201111/1a1394ac/attachment.html>
------------------------------
Subject: Legenda do Digest
_______________________________________________
Lista brasileira de usuários de shell script
Endereço de e-mail da lista: shell-script-pt@nongnu.org
Para se inscrever ou desinscrever acesse: https://lists.nongnu.org/mailman/listinfo/shell-script-pt
Para ver os arquivos da lista (mensagens anteriores) e pesquisar nelas, acesse https://lists.nongnu.org/archive/html/shell-script-pt/
NOTA: A lista anterior, no Yahoo Groups, foi *desativada*. Por favor utilize somente esta.
------------------------------
Fim da Digest shell-script-pt, volume 11, assunto 6
***************************************************
[Prev in Thread] | Current Thread | [Next in Thread] |