Controlando a ordem em que os arquivos são colocados em uma matriz

3

Eu tenho um script que pega um monte de arquivos com data e hora e os coloca em um array para ser processado pelo Mutt e enviado para mim. Meu problema é que os arquivos são colocados aleatoriamente no array e, como tal, são enviados por e-mail para mim em uma bagunça desordenada. Existe uma maneira de controlar a ordem em que esses arquivos são colocados na matriz? Eu gostaria que eles fossem ordenados por data. Aqui está o script que estou usando:

#!/bin/bash
date=$(date +%F)
recipients="[email protected]"
body="Found these files:"
mapfile -t files < <(find /my/directory -name '*.jpg' -newermt '-15 seconds' -not -newermt '-2 seconds')

if [ -z "$files" ]; then
body="No files were found"
echo "$body" | mutt -s "Error on $TODAY" $recipients
fi

echo "$body" | mutt -s "Files found on $date" -a "${files[@]}" -- $recipients
echo "${files[@]}"
    
por Yllier123 27.10.2015 / 14:32

1 resposta

4

Use zsh em vez de bash , onde você pode definir a classificação (por nome por padrão):

files=(/my/directory/**/*.jpg(.NDms+2ms-15))

Isso também evitará problemas com nomes de arquivo contendo caracteres de nova linha ( bash-4.4 ' mapfile suporta -d '' , que pode ser usado com find -print0 ).

Para classificar ( o rder) pelo m tempo de odificação:

files=(/my/directory/**/*.jpg(.NDms+2ms-15om))

Para obter um pedido similar (por nome) com o GNU find e o GNU sort :

find /my/directory -name '*.jpg' \
                   -type f \
                   -newermt '-15 seconds' \
                   ! -newermt '-2 seconds' \
                   -print0 |
  sort -zt/ -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 -k6,6 -k7,7 -k8,8 \
            -k9,9 -k10,10 -k11,11 -k12,12 -k13,13 -k14,14

Por ordem do tempo de modificação:

find /my/directory -name '*.jpg' \
                   -type f \
                   -newermt '-15 seconds' \
                   ! -newermt '-2 seconds' \
                   -printf '%T@:%p
files=(/my/directory/**/*.jpg(.NDms+2ms-15))
' | sort -zn | sed -z 's/[^:]*://#'

Adicione | tr 'readarray' '\n' para armazenar em uma variável bash escalar (não matriz) ou use com mapfile / -d '' sem readarray -d '' array < <(find...) (dividir em nova linha, caso em que você pode assim como a coisa toda em registros delimitados por nova linha em vez de registros delimitados por NUL).

Ou use zsh com bash 4.4 ou superior ou em array=(${(0)"$(find...)"}) , use %code% .

    
por 27.10.2015 / 14:51

Tags