최신 파일 자동 완성

최신 파일 자동 완성

생성 순간의 타임스탬프를 기반으로 파일 이름을 가진 텍스트 파일을 생성하는 프로세스가 있습니다.

$ ls
1378971222.txt
1378971254.txt
1378971482.txt
1378971488.txt
1378972089.txt
1378972140.txt
1378972141.txt
1378972153.txt
1378972155.txt
1378972241.txt

최근 생성된 파일의 파일 이름을 자동 완성하려면 어떻게 해야 합니까?, 즉 최신 mtime이 포함된 파일인가요? 파일 이름의 거의 모든 문자가 다른 파일과 공유되므로 이러한 파일에서는 탭 완성 기능을 사용할 수 없습니다. 단축키( Alt .마지막 명령의 마지막 인수 자동 완성 과 같은)를 찾고 싶습니다 . 저는 훌륭하게 작동하는 다음 별칭을 만들었습니다. 하지만 , 및 기타 앱에서 작동하는 VIM범용 단축키가 있는지 알고 싶습니다.kde-opensqlite3

alias lastest="vim `ls -t | grep -vE "^total [0-9]*$" | head -n1`"

답변1

당신은 할 수쉽게 구성하세요zsh, 예를 들어 다음과 같습니다.

zstyle ':completion:*' file-sort date

(스타일이 특정 파일 이름 패턴에만 사용되도록 이 줄을 변경할 수도 있습니다)

zshbash와 매우 유사하며 기능/사용 측면에서 bash의 상위 집합이라고 부를 수 있습니다.

하지만 아마도 bash에는 비슷한 기능이 있을 수도 있습니다.

답변2

vim별칭에서 제거하면 됩니다. 다음과 같이 하십시오:

alias latest='ls -tr | tail -n 1'

그런 다음 어떤 프로그램에서든 최신 파일을 열 수 있습니다.

emacs `latest`
ls `latest`
mv `latest` ../

등.

그러나 파일 이름에 공백이나 이상한 문자가 포함되어 있으면 중단됩니다.절대 파싱하면 안 된다ls. 더 좋은 방법은 다음과 같습니다(귀하의 방법에 추가하세요 .bashrc).

function latest(){
  $1 "$(find . -type f -printf "%C@ %p\n" | sort | tail -n 1 | cut -d " " -f 2-)"
}

이 함수는 인수로 제공한 모든 명령을 실행하고 find호출 결과(최신 파일)를 명령에 전달합니다. 따라서 다음을 수행할 수 있습니다.

latest emacs
latest less

비슷한 작업을 수행할 수 있어야 하는 경우 mv $(latest) foo/다음을 시도해 보십시오.

function latest(){
   A=(${@})
   prog=$1;
   lat=$(find . -type f -printf "%C@ %p\n" | sort | tail -n 1 | cut -d " " -f 2-)
   if [ ! -z $2 ] ; then 
     args=${A[@]:1}; 
     $prog "$lat" "${A[@]:1}"
   else
     $prog "$lat"
   fi
}

그런 다음 최신 파일을 에 복사하려면 bar/다음을 수행하십시오.

latest cp bar

그리고 여전히 latest emacs이전과 동일하게 할 수 있습니다.

답변3

마지막 파일 이름을 사용하여 탭 완성을 허용하도록 bash 완료 "_filedir" 함수를 수정합니다. source이 작업을 수행하는 스크립트 는 다음과 같습니다 .

#!/bin/sh

_filedir_newest()
{
    local parent="$1"
    if [ "${#parent}" -gt "0" ]; then
        parent="$(compgen -d -- ${1:0:-1})/"
    fi
    newest=$(bash -c "ls -tr $parent | tail -n 1")
    echo "$parent$newest"
} # _filedir_newest()

_filedir()
{
    local IFS=$'\n'

    _tilde "$cur" || return

    local -a toks
    local x reset
    local newest=0

    reset=$(shopt -po noglob); set -o noglob
    toks=( $(compgen -d -- "$cur") )
    IFS=' '; $reset; IFS=$'\n'

    if [[ "$1" != -d ]]; then
        local quoted
        if [[ "$cur" = "?" ]] || [[ "${cur: -2}" = "/?" ]]; then
            cur="${cur:0:-1}"
            newest=1
        fi
        _quote_readline_by_ref "$cur" quoted

        # Munge xspec to contain uppercase version too
        # http://thread.gmane.org/gmane.comp.shells.bash.bugs/15294/focus=15306
        local xspec=${1:+"!*.@($1|${1^^})"}
        reset=$(shopt -po noglob); set -o noglob
        toks+=( $(compgen -f -X "$xspec" -- $quoted) )
        IFS=' '; $reset; IFS=$'\n'

        # Try without filter if it failed to produce anything and configured to
        [[ -n ${COMP_FILEDIR_FALLBACK:-} && -n "$1" && ${#toks[@]} -lt 1 ]] && {
            reset=$(shopt -po noglob); set -o noglob
            toks+=( $(compgen -f -- $quoted) )
            IFS=' '; $reset; IFS=$'\n'
        }
    fi

    if [[ ${#toks[@]} -ne 0 ]]; then
        # 2>/dev/null for direct invocation, e.g. in the _filedir unit test
        compopt -o filenames 2>/dev/null
        if [[ $newest -eq 1 ]]; then
            COMPREPLY+=( $(_filedir_newest "$cur") )
        else
            COMPREPLY+=( "${toks[@]}" )
        fi
    fi
} # _filedir()

_filedir_xspec()
{
    local cur prev words cword
    _init_completion || return

    _tilde "$cur" || return

    local IFS=$'\n' xspec=${_xspecs[${1##*/}]} tmp
    local -a toks
    local newest=0

    if [[ "$cur" = "?" ]] || [[ "${cur: -2}" = "/?" ]]; then
        cur="${cur:0:-1}"
        newest=1
    fi

    toks=( $(
        compgen -d -- "$(quote_readline "$cur")" | {
        while read -r tmp; do
            printf '%s\n' $tmp
        done
        }
        ))

    # Munge xspec to contain uppercase version too
    # http://thread.gmane.org/gmane.comp.shells.bash.bugs/15294/focus=15306
    eval xspec="${xspec}"
    local matchop=!
    if [[ $xspec == !* ]]; then
        xspec=${xspec#!}
        matchop=@
    fi
    xspec="$matchop($xspec|${xspec^^})"

    toks+=( $(
        eval compgen -f -X "'!$xspec'" -- "\$(quote_readline "\$cur")" | {
        while read -r tmp; do
            [[ -n $tmp ]] && printf '%s\n' $tmp
        done
        }
        ))

    if [[ ${#toks[@]} -ne 0 ]]; then
        compopt -o filenames
        if [[ $newest -eq 1 ]]; then
            COMPREPLY=( $(_filedir_newest "$cur") )
        else
            COMPREPLY=( "${toks[@]}" )
        fi
    fi
} # _filedir_xspec()

모든 bash 세션에서 작동하도록 다음과 같이 추가 ~/.bashrc( 적절하게 교체)할 수 있습니다./path/to/the/script

source /path/to/the/script/_filedir.sh

설치 후 "?"는 디렉토리의 마지막 파일을 나타내는 특수 표시로 사용됩니다. 예:

eog ~/Downloads/?<TAB>

(한 경우에):

eog ~/Downloads/Sunscreen\ Permission\ -\ ToddlerPrimaryElementary.pdf

이 기술은 현재 디렉터리의 최신 파일만 보고하는 것이 아니라 bash 완성 시스템과 통합되므로 모든 디렉터리에서 작동합니다. 나는 종종 이 기능을 사용하여 브라우저에서 최근에 다운로드한 파일을 현재 작업 중인 프로젝트의 폴더( mv ~/Downloads/?<TAB> .)로 이동합니다.

2021년 10월 27일에 업데이트됨:_filedir_xspec이제 bash 자동 완성 루틴에서도 작동합니다.2021년 11월 9일에 업데이트됨:마지막 업데이트 이후 현재 디렉터리에서 작업할 때 발생하는 버그를 수정했습니다.

답변4

질문의 배경은 사용 속도입니다. 저는 키보드 매크로가 가장 잘 작동한다고 생각합니다. 다음에 추가 ~/.inputrc:

# Alt-L --> newest file in directory
"\el": "$(ls -t|head -1)"

추가 생각:처음에는 첫 번째, 두 번째, 세 번째 최신 파일을 제공하는 것을 원했습니다. 한 가지 아이디어는 이러한 위치를 "grep x _"와 같은 마커로 표시한 다음 키보드 매크로 "\C-alatest-expansion \Cm"을 실행하는 것입니다. "latest-expansion"을 선택하면 저주 선택 목록이 표시됩니다. 명령줄에서 각 "_" 표시에 대한 최신 파일입니다.

SHELL에 비해 GUI의 또 다른 장점은 최근 사용/생성된 파일과 디렉터리를 선택할 수 있다는 점이므로 이것이 중요한 질문이라고 생각합니다. autojump디렉토리에 대해서는 약간의 도움이 되지만 파일에 대한 솔루션은 없습니다.

관련 정보