O shell bash
(e um número de outros shells) tem um operador de teste -nt
não padrão. Este operador testa se a hora da modificação em um arquivo é mais nova que a outra.
Em bash
, o operador -nt
tem uma resolução de tempo de um segundo. Em ksh93
, pode-se usar o mesmo operador com resolução de sub-segundo. O código abaixo é compatível com ksh93
, exceto que shopt -s globstar
precisa mudar para set -o globstar
quando esta opção é usada.
Usando o operador -nt
test nos arquivos que correspondem a *.txt
no diretório atual para encontrar o arquivo regular mais recente:
unset newest
for filename in ./*.txt; do
if [ -f "$filename" ] && [ "$filename" -nt "$newest" ]; then
newest=$filename
fi
done
ou, um pouco mais curto,
unset newest
for filename in ./*.txt; do
[ -f "$filename" ] && [ "$filename" -nt "$newest" ] && newest=$filename
done
No final do loop, o valor "$newest"
seria o nome do arquivo regular modificado mais recentemente no diretório atual que tem um sufixo de nome de arquivo .txt
, desde que esses arquivos existissem ( caso contrário, a variável newest
não seria definida).
O shell dash
, se isso for usado, precisaria de um teste separado para a existência do arquivo $newest
, pois seu operador -nt
tem semântica um pouco diferente de bash
e ksh93
:
unset newest
for filename in ./*.txt; do
if [ -f "$filename" ]; then
if [ ! -f "$newest" ] || [ "$filename" -nt "$newest" ]; then
newest=$filename
fi
fi
done
Para fazer isso de forma recursiva com bash
, defina a opção globstar
shell e use **
para fazer o globbing de nome de arquivo:
shopt -s globstar
unset newest
for pathname in ./**/*.txt; do
if [ -f "$pathname" ] && [ "$pathname" -nt "$newest" ]; then
newest=$pathname
fi
done
O padrão **
corresponde a *
, mas permite a correspondência entre /
em nomes de caminho.
O shell dash
não suporta isso.
Com base no código anterior, para obter os cinco arquivos modificados mais recentemente:
shopt -s globstar
unset newest
for pathname in ./**/*.txt; do
if [ -f "$pathname" ]; then
for (( i=0; i < 5; ++i )); do
if [ "$pathname" -nt "${newest[$i]}" ]; then
newest=( "${newest[@]:0:i}" "$pathname" "${newest[@]:i:4}" )
break
fi
done
fi
done
A única coisa extra aqui é que newest
agora é uma matriz bash
, e que nós, para cada nome de caminho que consideramos, temos que percorrer os cinco "arquivos mais recentes" encontrados mais recentemente para ver onde array este novo arquivo pode se encaixar.
Quando descobrimos que o arquivo é de fato mais novo do que um dos outros arquivos na matriz, combinamos o novo nome de caminho na matriz e ao mesmo tempo limitamos o número de elementos a cinco.
Após o término do loop, a matriz newest
manterá os nomes de caminho dos cinco arquivos regulares modificados mais recentemente com um sufixo .txt
nomes de arquivos. A matriz será classificada na hora da modificação, com o arquivo modificado mais recentemente como ${newest[0]}
.