Como obtenho os 6 dígitos do meio de um caminho de arquivo

Como obtenho os 6 dígitos do meio de um caminho de arquivo

Eu tenho um nome de caminho de arquivo como

/dbfs/mnt/dlg2stage/foldername/backupname/201906_load_1_20210623-151602.tar.tgz

Estou tentando obter apenas os 201906 dígitos de seis dígitos e imprimi-los. Eu tentei sede awkmas falhei.

Responder1

Supondo que esses arquivos sejam reais em seu sistema, você pode extrair facilmente a parte anterior à primeira _nos nomes de arquivo de cada arquivo correspondente *_*.tar.tgzno diretório /dbfs/mnt/dlg2stage/foldername/backupnameusando um loop de shell:

for pathname in /dbfs/mnt/dlg2stage/foldername/backupname/*_*.tar.tgz; do
    name=$( basename "$pathname" )
    printf '%s\n' "${name%%_*}"
done

O basenameutilitário fornecerá a parte do nome do arquivo de um nome de caminho. Dado o exemplo que você mostra, isso atribuiria a string 201906_load_1_20210623-151602.tar.tgzà variável name. Você também poderia ter feito name=${pathname##*/}a mesma coisa (esta expansão de parâmetro remove a seção inicial da string em $pathname, até e incluindo a última /).

A expansão do parâmetro ${name%%_*}resultaria na _*remoção da correspondência de substring mais longa do valor $name. Com o exemplo mostrado, isso removeria o primeiro _caractere e tudo à direita dele, deixando a substring 201906, que é então impressa usando printf.

Responder2

Com zsh:

file=/dbfs/mnt/dlg2stage/foldername/backupname/201906_load_1_20210623-151602.tar.tgz
set -o extendedglob # for (#c6)

first_6_digits_of_file_tail=${(M)${file:t}[0-9](#c6)}

Onde ${file:t}leva ocaudado arquivo (seu nome base), ${(M)var#pattern}retorna a parte no início $varque Matribui o padrão.

POSIXly, você pode usar:

first_6_digits_of_file_tail=$(
  LC_ALL=C expr "/$file" : '.*/\([0-9]\{6\}\)[^/]*/*$'
)

LC_ALL=Cignorar a localidade do usuário e considerar todos os bytes como caracteres (os 128 primeiros conforme ASCII na maioria dos sistemas, incluindo / e 0123456789 dígitos) para que .e [^/]seja garantido que corresponda aos bytes e [0-9]inclua apenas 0123456789. Não são dígitos zshonde os intervalos são baseados em codepoints e zsh consideram cada byte que não faz parte de caracteres válidos como se fosse um caractere.

Anexar /para evitar problemas com valores $fileque começam com -ou se parecem com exproperadores e também para garantir que as strings contenham pelo menos um /conforme esperado pelo regexp.

Não permitimos /que s após o /XXXXXXexceto no final obtenham o mesmo comportamento que soluções usando basenameor zsh $file:tonde o nome base de /foo/bar/or /foo/bar////é bar.

Cuidado, ele retorna um status de saída falso/falha se não houver correspondência, mas também se essa sequência de 6 dígitos representar o número 0 (como em /path/to/000000_whatever).

Responder3

Eu acho que você só quer imprimir 201906dada essa string de caminho. Nesse exemplo, esses seis dígitos são:os primeiros seis dígitos que têm uma barra na frente deles.

Estou colocando o caminho em uma variável apenas para facilitar a leitura do comando:

% path_str='/dbfs/mnt/dlg2stage/foldername/backupname/201906_load_1_20210623-151602.tar.tgz'

% echo $path_str | sed 's/.*\/\([0-9]\{6\}\).*/\1/'
201906

Veja como construí essa correspondência e substituição emsed:

  • \/[0-9]\{6\}: corresponde a uma barra e 6 dígitos
  • \/\([0-9]\{6\}\): é o mesmo, mas agora em umgrupo de capturaousubexpressão(a barra não está no grupo de captura)
  • .*\/\([0-9]\{6\}\).*: combina com tudo antes e depois, então...toda a linha
  • \1: com toda a linha correspondida, use a referência para oprimeiro(e apenas) grupo de captura para substituir a linha inteira apenas pelos primeiros 6 dígitos

informação relacionada