最新のファイルオートコンプリート

最新のファイルオートコンプリート

作成時点のタイムスタンプに基づいてファイル名を持つテキストファイルを生成するプロセスがあります。

$ 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これでb​​ashオートコンプリートルーチンでも動作します。2021年11月9日に更新:最後の更新以降に現在のディレクトリで作業していたときに発生するバグを修正しました。

答え4

質問の背景は使用速度です。私はキーボードマクロが最もうまくいくと思います。次に追加~/.inputrc:

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

追加の考え:最初は、最初、2番目、3番目の最新のファイルを提供したいと思いました。 1つのアイデアは、これらの位置を「grep x _」などのマーカーとしてマークし、キーボードマクロ「\ C-alatest-expansion \ Cm」を実行することです。 「latest-expansion」を選択すると、呪い選択リストが表示されます。コマンドラインの各「_」マークの最新ファイル。

SHELLに比べてGUIのもう一つの利点は、最近使用/生成されたファイルとディレクトリを選択できることですので、これが重要な質問だと思います。autojumpディレクトリについては少し役に立ちますが、ファイルに対する解決策はありません。

関連情報