É possível referenciar o arquivo modificado mais recentemente em um argumento de linha de comando?

6

Freqüentemente, faço o download de arquivos PDF com nomes de arquivos numéricos hediondos do meu navegador. Estes entram automaticamente em ~/Downloads . Idealmente, gostaria de poder abrir esses arquivos com:

evince "the most recently modified file"

sem ter que abrir ~/Downloads para encontrar o nome do arquivo.

Existe uma maneira simples de especificar "o arquivo modificado mais recentemente" em bash ?

NOTA: Eu sei que é possível fazer isso, mas o ideal é procurar uma solução que seja mais simples do que ls -t 'ing ~/Downloads para verificar o nome.

    
por KennyPeanuts 22.03.2012 / 14:03

5 respostas

9
evince "$(ls -t | head -n1)"

Embora ele manipule espaços, tabulações e (acredito) que imprimam especiais, ele será interrompido se o nome do arquivo contiver uma nova linha e possivelmente em alguns outros caracteres não imprimíveis.

    
por 22.03.2012 / 14:16
4

Esta é uma abordagem mais correta e robusta do que ls -t , ao custo de alguma complexidade adicional.

Configuração

Adicione um script de shell curto (código abaixo) ao seu $PATH . ~/bin é um bom lugar para isso.

Lembre-se de garantir que

  • o script é executável chmod +x ~/bin/script_name
  • ~/bin está no seu $PATH

Uso

Passe o comando que você deseja executar no arquivo mais recente em ~/Download to last_download .

Exemplos

Supondo que você nomeou o script last_download

  • last_download (sem argumentos): executa evince , o comando padrão, no arquivo mais recente em ~/Downloads
  • last_download mplayer : executa mplayer no arquivo mais recente em ~/Downloads
  • last_download cp -t ~/Desktop : copia o arquivo mais recente em ~/Downloads para ~/Desktop

Código

#!/bin/sh
# Usage: last_download [cmd [options]...]

newest=
dir=~/Downloads

# default command
if [ $# -eq 0 ]; then
        set -- evince;
fi

# find newest file
for f in "$dir"/*; do
        if [ -z "$newest" ] || [ "$f" -nt "$newest" ]; then
                newest="$f"
        fi
done
if ! [ -e "$newest" ]; then
        exit 1
fi

# run command on newest file
"$@" "$newest"

Nota: O script procura apenas em ~/Download , mas não seria difícil generalizá-lo para suportar qualquer diretório, caso em que uma mudança de nome também seria justificada.

    
por 22.03.2012 / 16:49
4
exec zsh
evince ~/Downloads/*.pdf(om[1])

ou se você não quiser mudar para o zsh

cd ~/Downloads
zsh -c 'evince ./*.pdf(om[1])'

Os bits entre parênteses são qualificadores da glob. om altera a ordem em globs para usar o horário da modificação em vez do nome (o mais novo primeiro). [1] significa usar apenas a primeira correspondência.

Para mais informações, consulte esta resposta para "Como filtrar um glob no zsh" .

    
por 23.03.2012 / 02:42
3

Você pode usar um find_date_sorted modificado:

last_download() {
    while IFS= read -r -d '' -u 9
    do
        cut -d ' ' -f 3- <<< "$REPLY"
        break
    done 9< <(find ~/Downloads -maxdepth 1 -type f -printf '%TY-%Tm-%Td %TH:%TM:%TS %p
evince "$(last_download)"
' | sort -rz) }

Funcionará com qualquer nome de arquivo. Para abrir o arquivo:

last_download() {
    while IFS= read -r -d '' -u 9
    do
        cut -d ' ' -f 3- <<< "$REPLY"
        break
    done 9< <(find ~/Downloads -maxdepth 1 -type f -printf '%TY-%Tm-%Td %TH:%TM:%TS %p
evince "$(last_download)"
' | sort -rz) }
    
por 22.03.2012 / 16:19
0

Não, e mesmo se houvesse, você não poderia ter certeza de que algum log do sistema normalmente não seria o arquivo atualizado mais recentemente.

A resposta de Kevin (ele me bateu nela) funciona se você quiser apenas evitar manualmente abrindo ~/Downloads .

    
por 22.03.2012 / 14:18