我有一个创建文本文件的过程,其文件名基于创建时刻的时间戳:
$ 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-open
sqlite3
alias lastest="vim `ls -t | grep -vE "^total [0-9]*$" | head -n1`"
答案1
答案2
vim
只需从别名中删除即可。做这样的事情:
alias latest='ls -tr | tail -n 1'
然后您可以使用任何程序打开最新的文件:
emacs `latest`
ls `latest`
mv `latest` ../
ETC。
但是,如果您的文件名包含空格或奇怪的字符,这将会中断,这就是您的原因永远不应该解析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()
可以将其添加到您的~/.bashrc
像这样(/path/to/the/script
适当替换),以便它适用于所有 bash 会话:
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”会提示一个curses-selection列表以供选择命令行中每个“_”标记的最新文件。
我认为这是一个重要的问题,因为 GUI 相对于 SHELL 的另一个优势是对我来说可以选择最近使用/创建的文件和目录。autojump
对目录有一点帮助,但缺少文件的解决方案。