Combinando nomes numéricos não consecutivos de arquivos

0

Estou tentando executar um comando para corresponder a um determinado subconjunto de arquivos em um diretório. Todos os arquivos têm um nome timestamp .jpg, com aproximadamente (mas não exatamente) 30 minutos entre cada arquivo.

Com base em esta pergunta e resposta , Eu criei este comando (usando echo para testar):

for x in *([1510852838790,1510898258530]).jpg; do echo $x; done

No entanto, isso gera o seguinte (observe os números de entrada marcados com ****):

1510770572978.jpg
1510770810272.jpg
1510772133873.jpg
1510772378293.jpg
1510772979803.jpg
1510773223237.jpg
1510852838790.jpg****
1510852959075.jpg
1510853079321.jpg
1510853808012.jpg
1510855019583.jpg
1510855380099.jpg
1510855983715.jpg
1510857313787.jpg
1510858282007.jpg
1510858889310.jpg
1510859009339.jpg
1510859253091.jpg
1510870852822.jpg
1510871097118.jpg
1510871335799.jpg
1510871703808.jpg
1510871823158.jpg
1510872311110.jpg
1510872553750.jpg
1510872917378.jpg
1510873159981.jpg
1510875721755.jpg
1510877181978.jpg
1510877301888.jpg
1510878157813.jpg
1510878278033.jpg
1510878522553.jpg
1510879250080.jpg
1510879738575.jpg
1510879859397.jpg
1510880105392.jpg
1510880717151.jpg
1510880957839.jpg
1510881325005.jpg
1510881570373.jpg
1510881811325.jpg
1510882295590.jpg
1510882785823.jpg
1510883275381.jpg
1510885101702.jpg
1510885222385.jpg
1510885711900.jpg
1510887172253.jpg
1510887292977.jpg
1510887538312.jpg
1510888029878.jpg
1510889975298.jpg
1510890221372.jpg
1510890709993.jpg
1510890830832.jpg
1510890951888.jpg
1510891193150.jpg
1510891313575.jpg
1510891922503.jpg
1510892537090.jpg
1510892900397.jpg
1510893021713.jpg
1510893385557.jpg
1510893992777.jpg
1510895212923.jpg
1510895333595.jpg
1510895819713.jpg
1510897039331.jpg
1510897159572.jpg
1510898133110.jpg
1510898258530.jpg****
1510900807071.jpg
1510900927933.jpg
1510902272277.jpg
1510902393272.jpg
1510902998172.jpg
1510903851131.jpg
1510905309558.jpg
1510905557228.jpg
1510907015107.jpg
1510907751301.jpg
1510907877003.jpg
1510907992905.jpg
1510908113731.jpg
1510908598199.jpg
1510908719029.jpg
1510909570015.jpg
1510909811208.jpg
1510909931529.jpg
1510910181722.jpg
1510911388852.jpg
1510911513951.jpg
1510911879905.jpg
1510912727850.jpg
1510913088390.jpg
1510913818319.jpg
1510915397801.jpg
1510917103919.jpg
1510917711228.jpg
1510917832327.jpg
1510917953273.jpg
1510918319775.jpg
1510918803832.jpg
1510918929550.jpg
1510919172181.jpg
1510919293195.jpg
1510919898053.jpg
1510922089190.jpg
1510922579951.jpg
1510923308092.jpg
1510923550590.jpg
1510923793010.jpg
1510925011829.jpg
1510925137958.jpg
1510925987153.jpg
1510927083913.jpg
1510927812212.jpg
1510928298155.jpg
1510928910223.jpg
1510929031559.jpg
1510930370780.jpg
1510930733981.jpg
1510930981902.jpg
1510932080591.jpg
1510932809212.jpg
1510933290952.jpg
1510933903131.jpg
1510935121827.jpg
1510935237921.jpg
1510935725717.jpg
1510937189535.jpg
1510937919235.jpg
1510938283032.jpg
1510938895279.jpg
1510939137978.jpg
1510939501755.jpg
1510939992901.jpg

A lista de saída contém 138 nomes de arquivos dos arquivos 798 no diretório, mas contém arquivos adicionais antes do primeiro número de entrada e após o segundo número de entrada. Por que isso e como corrijo isso?

    
por lucasvw 17.11.2017 / 20:33

2 respostas

2

[1510852838790,1510898258530] é um operador glob padrão que corresponde a um caractere no conjunto de caracteres. [ab,c] corresponde a a , b , , ou c . Então [1510852838790,1510898258530] é o mesmo que [,01235789] ou [,0-357-9] . Ou seja, corresponde a vírgulas ou dígitos decimais diferentes de 4 e 6 .

*(...) é um operador glob do shell Korn (também suportado por zsh -o kshglob e bash -O extglob ) que corresponde a 0 ou mais ... .

Portanto, *([1510852838790,1510898258530]).jpg corresponde a qualquer sequência de ,01235789 caracteres seguida por .jpg .

Se você quisesse corresponder qualquer string que consistisse em um número decimal entre 1510852838790 e 1510898258530, você precisaria do operador <x-y> glob do zsh shell:

printf '%s\n' <1510852838790-1510898258530>.jpg

A resposta à qual você está vinculando refere-se a outro recurso do shell zsh (novamente não bash ): o qualificador [x,y] glob.

Qualificadores Glob é uma parte (...) que é adicionada ao final de uma glob para adicionar alguns critérios diferentes daqueles baseados no nome.

Por exemplo, *.jpg(.) é *.jpg mas limitado a arquivos regulares (excluindo diretórios, links simbólicos, sockets, fifos ...)

*.jpg([5,10]) é o quinto ao décimo arquivos na lista de arquivos que correspondem a *.jpg (classificados em modo léxico).

Observe que os qualificadores zsh glob estão em conflito com kshglob . Se você quiser usar kshglob (mas geralmente você não o faria, a menos que queira interpretar o código pretendido para ksh como zsh extendedglobs são geralmente melhores que os ksh), você geralmente também deseja desabilitar a opção bareglobqual (ou use o comando o modo de emulação ksh com emulate ksh que cuidaria disso e também permitiria mais comportamentos semelhantes ao ksh).

O equivalente a ksh ' *(x) em zsh extended globs é x# (como regexp x* , exceto que em globs * é usado para outra coisa).

bash não tem o operador <x-y> glob nem os qualificadores glob. Em bash , você pode fazer:

zsh -c "printf '%s\n' <1510852838790-1510898258530>.jpg"

Ou você pode imprimir todos os arquivos number.jpg e postar a saída com awk :

shopt -s extglob
printf '%s\n' *([0-9]).jpg |
  awk -F. '$1 >= 1510852838790 && $1 <= 1510898258530'

De qualquer forma, se você vai tentar encontrar lacunas na sequência de números, provavelmente vai querer usar awk de qualquer maneira.

Como (de volta a usar zsh ):

print -l <->.jpg(n) | awk -F. '
  {diff = ($0 - prev) / 1000 / 60}
  NR > 1 && (diff < 29 || diff > 31) {print $0, "diff=" diff}
  {prev = $0}'
    
por 17.11.2017 / 20:51
0

Se os seus nomes de arquivos forem todos carimbos de data e hora, você poderá compará-los dentro de um contexto aritmético (( )) . Isso obtém todos os arquivos com nome numérico jpg , retira a extensão e compara-os com seus limites superior e inferior:

#!/bin/bash

shopt -s extglob

for f in *([0-9]).jpg; do
   timestamp="${f%%.*}"
   (( "$timestamp" >= 1510852838790 && "$timestamp" <= 1510898258530 )) && echo "$f"
done

exit
    
por 20.11.2017 / 21:56

Tags