Posso selecionar apenas um resultado de um bash glob?

13

Estou tentando escrever um script para o trabalho para automatizar alguns relatórios sobre uma saída. Os arquivos de log são (atualmente, estão sendo 'padronizados' no futuro) armazenados neste tipo de estrutura de caminho:

/<root_path>/<process_one_path>/logs/<time_date_stamp>/<specific_log_file>

/<root_path>/<process_two_path>/logs/<different_time_date_stamp>/<specific_log_file>

Todas as partes do caminho são conhecidas, exceto os carimbos de data e hora, que são sempre os mais recentes na pasta.

Se eu tentar usar um curinga no lugar do carimbo de data e hora, obtenho vários resultados, por exemplo:

> ls /<root_path>/<process_two_path>/logs/* [tab]
20130102-175103
20130118-090859
20130305-213506

Eu só quero que ele retorne o mais recente, isso é possível com o Bash?

NB (Eu não tenho zsh, e por mais adorável que pareça, duvido que algum dia trabalhemos com ele)

    
por Pureferret 05.04.2013 / 22:34

5 respostas

8

Os seguintes trabalhos no bash 4.2:

list=( /<root_path>/<process_two_path>/logs/* )
echo "${list[-1]}"

Se o seu bash é uma versão mais antiga:

list=( /<root_path>/<process_two_path>/logs/* )
echo "${list[${#list[@]}-1]}"
    
por 05.04.2013 / 22:59
10

POSIXly:

 set -- /<root_path>/<process_two_path>/logs/*
 shift "$(($# - 1))"
 printf '%s\n' "$1"

Como você mencionou zsh :

 print -r /<root_path>/<process_two_path>/logs/*([-1])
    
por 05.04.2013 / 23:12
4

Use o bash glob em um bash for loop. Assim:

for filename in <logdir>/*; do :; done; echo "$filename"

Isso depende do fato de que o bash faz a expansão glob em ordem alfabética. Leia o manual do bash para obter mais informações. Observe que isso depende de LC_COLLATE . Isso também depende do fato de que a variável filename ainda contém o último valor após o término do loop.

Se você quiser o nome do arquivo com o timestamp mais antigo, você pode fazer assim:

for filename in <logdir>/*; do echo "$filename"; break; done
    
por 05.04.2013 / 23:12
0

-1 é o padrão em pipelines e ls já deve estar classificado:

ls | tail -n1

Se outras pessoas estivessem procurando como inserir o primeiro ou o último resultado de forma interativa, você pode vincular o menu completo ou o menu completo para trás em .inputrc:

"\e\t": menu-complete
"\e[Z": menu-complete-backward # shift-tab

Se show-all-if-ambiguous estiver ativado, set completion-query-items 0 removerá o prompt quando houver 101 ou mais resultados e set page-completions off desativar o pager.

    
por 06.04.2013 / 04:44
-1
ls -tr | tail -1

Deve fazer o truque.

    
por 06.04.2013 / 08:23