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

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

Re: [shell-script-pt] Digest shell-script-pt, volume 11, assunto 6


From: Arkanon
Subject: Re: [shell-script-pt] Digest shell-script-pt, volume 11, assunto 6
Date: Thu, 12 Nov 2020 08:14:55 -0300

Por isso a ressalva do "padrão rígido que parecia seguir", Vilmar: sempre que criar uma amostra, tente fazê-la da forma mais representativa possível.
Em algum momento no seu e-mail original, pareceu que pode haver uma estrutura de subdiretórios dentro de /var/cache/fetch/archives. Se for o caso, adicione à amostra.

Com essa sua segunda amostra, volto a recorrer à primeira ideia que tinha me ocorrido, antes de perceber a simplificação com dois sort's que satisfazia a amostra anterior:

$ 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
/var/cache/fetch/archives/linux-5.9.8.arch1-1-x86_64.chi.zst
/var/cache/fetch/archives/linux-5.9.7.arch1-1-x86_64.chi.zst
/var/cache/fetch/archives/linux-api-headers-5.8-1-any.chi.zst
/var/cache/fetch/archives/linux-docs-5.8.3.arch1-1-x86_64.chi.zst
/var/cache/fetch/archives/linux-firmware-20201023.dae4b4c-1-any.chi.zst
/var/cache/fetch/archives/linux-headers-5.9.7.arch1-1-x86_64.chi.zst
/var/cache/fetch/archives/linux-headers-5.9.8.arch1-1-x86_64.chi.zst

$ sort -Vr pacotes.txt | rev | tr - '\t' | uniq -f3 | tr '\t' - | rev | tac
/var/cache/fetch/archives/linux-5.9.8.arch1-1-x86_64.chi.zst
/var/cache/fetch/archives/linux-api-headers-5.8-1-any.chi.zst
/var/cache/fetch/archives/linux-docs-5.8.3.arch1-1-x86_64.chi.zst
/var/cache/fetch/archives/linux-firmware-20201023.dae4b4c-1-any.chi.zst
/var/cache/fetch/archives/linux-headers-5.9.8.arch1-1-x86_64.chi.zst
/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


A base de toda essa ideia é o parâmetro -f do uniq.
Como o uniq não tem um parâmetro equivalente ao -f para ignorar os ÚLTIMOS campos, com o rev tornamos os últimos campos em primeiros.
Como o uniq não tem um parâmetro especial para indicar o delimitador de campos, com o tr substituímos temporariamente o hifen por um tab. Talvez haja uma forma espertinha de usar o IFS com o uniq, mas assim, na corrida, não vi uma mais simples e eficiente que usando dois tr's.
Com o tac final, voltamos a ter a ordem crescente, mas bem que poderia ser deixado de lado.

Att,

Em qui., 12 de nov. de 2020 às 01:51, Vilmar Catafesta <vcatafesta@gmail.com> escreveu:
Olá Arkanon,

tua ideia em usar o 'sort' para filtrar é boa, porém
não funciona em todos os casos, veja:

# cat pacotes.txt
/var/cache/fetch/archives/linux-5.9.7.arch1-1-x86_64.chi.zst
/var/cache/fetch/archives/linux-5.9.8.arch1-1-x86_64.chi.zst
/var/cache/fetch/archives/linux-api-headers-5.8-1-any.chi.zst
/var/cache/fetch/archives/linux-docs-5.8.3.arch1-1-x86_64.chi.zst
/var/cache/fetch/archives/linux-firmware-20201023.dae4b4c-1-any.chi.zst
/var/cache/fetch/archives/linux-headers-5.9.7.arch1-1-x86_64.chi.zst
/var/cache/fetch/archives/linux-headers-5.9.8.arch1-1-x86_64.chi.zst

# sort -Vr pacotes.txt | sort -t- -k1,1 -u
/var/cache/fetch/archives/linux-headers-5.9.8.arch1-1-x86_64.chi.zst

observe que faltou vários, pacotes, tais como:
/var/cache/fetch/archives/linux-5.9.8.arch1-1-x86_64.chi.zst
/var/cache/fetch/archives/linux-api-headers-5.8-1-any.chi.zst
/var/cache/fetch/archives/linux-docs-5.8.3.arch1-1-x86_64.chi.zst
/var/cache/fetch/archives/linux-firmware-20201023.dae4b4c-1-any.chi.zst

Neste lista de pacotes.txt, tem arquivos também que somente tem uma 
versão, e deve permanecer ;)

Talvez usando ERs, o que me diz ?

Saudações


Em qua., 11 de nov. de 2020 às 21:26, <shell-script-pt-request@nongnu.org> escreveu:
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
***************************************************
_______________________________________________
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  (Twitter)     __o
//\   arkanon@lsd.org.br   _`\<,
V_/_      www.lsd.org.br  (_)/(_)
---------------------------------

reply via email to

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