Abrindo o arquivo modificado mais recentemente no vim

5

Os seguintes comandos funcionam

$ ls -1t | head -1
git_sync_log20180924_00.txt

$ vi git_sync_log20180924_00.txt

Mas isso não acontece

$ ls -1t | head -1 | vi
Vim: Warning: Input is not from a terminal
Vim: Error reading input, exiting...
Vim: preserving files...
Vim: Finished.

Como posso fazer isso (abra o arquivo modificado mais recentemente no vi)?

    
por IceCreamToucan 24.09.2018 / 15:10

3 respostas

13
vi -- "$(ls -t | head -n 1)"

(que assume nomes de arquivos não contêm caracteres de nova linha).

Ou se estiver usando zsh :

vi ./*(om[1])

Ou:

vi ./*(.om[1])

Para considerar apenas arquivos regulares .

vi ./*(.Dom[1])

Para também considerar arquivos ocultos (como se estivesse usando ls -At ).

Eles funcionam independentemente de quais valores de caracteres ou bytes os nomes de arquivos podem conter. Para um equivalente de utilitários e shell GNU, você pode fazer:

IFS= read -rd '' file < <(
  find . ! -name . -prune -type f -printf '%T@\t%p
vi -- "$(ls -t | head -n 1)"
' | sort -zrn | cut -zf2-) && vi "$file"
    
por 24.09.2018 / 15:13
6

Com sua estrutura de pipeline, você pode usar xargs da seguinte forma:

ls -1t | head -1 | xargs vi
    
por 24.09.2018 / 15:58
1

Se você precisar de uma solução mais sólida que não dependa da saída escamosa de ls , é possível recorrer a stat(1) . A maioria das implementações tem alguma maneira de especificar um formato de saída personalizado que pode incluir carimbos de data e hora para alimentar o sort(1) ou um script Awk. Alguns exemplos:

  • com os coreutils GNU:

    stat -L -c '%Y %n' -- *
    
  • com coreutils BSD:

    stat -L -t '%s' -f '%Sm %N' ./*
    

Posteriormente, você pode classificar e filtrar o resultado:

  • apenas com coreutils:

    stat ... | sort -t ' ' -k 1,1 -n -r | head -n 1 | cut -d ' ' -f 2-
    

    Isso requer tempo O (n log n) para ordenar toda a entrada, mesmo que você só precise do máximo.

  • com Awk:

    stat ... | awk -F ' ' 'NR == 1 || $1 > m { m = $1; n = substr($0, length(m) + 2); } END{ if (NR) print(n); }'
    

    Isso é executado em tempo O (n) porque compara e atualiza o máximo.

por 24.09.2018 / 19:32