我经常需要在 Bash 中完整复制输出行:
$ grep -ilr mysql_connect *
httpdocs/includes/config.php
httpdocs/admin/db.php
statistics/logs/error_log
$ vim httpdocs/includes/config.php
有什么方法可以配置 Bash 或 Tmux 快捷方式three lines up
,例如@@3
:
$ grep -ilr mysql_connect *
httpdocs/includes/config.php
httpdocs/admin/db.php
statistics/logs/error_log
$ vim @@3 # This would be the equivalent of vim httpdocs/includes/config.php (three lines up)
快捷方式不需要是@@
,其他任何东西都可以。理想情况下,这可以在任何 Bash 中工作,但 tmux 快捷方式也可以工作。
请注意,我熟悉 tmux 和屏幕复制和粘贴(进入粘贴模式,移动到复制,返回,粘贴),但我希望有一些我可以更轻松使用的东西(@@N),因为我似乎经常这样做。
答案1
以下 Bash 函数将使用运行命令(即grep -ilr mysql_connect *
)后获得的输出来创建一个列表,您可以从中选择一个选项(文件)。选择后,将使用 Vim 打开该文件。
output_selection()
{
local i=-1;
local opts=()
local s=
while read -r line; do
opts+=("$line")
printf "[$((++i))] %s\n" "$line"
done < <("$@")
read -p '#?' s
if [[ $s = *[!0-9]* ]]; then
printf '%s\n' "'$s' is not numeric." >&2
elif (( s < 0 )) || (( s >= ${#opts[@]} )); then
printf '%s\n' "'$s' is out of bounds." >&2
else
vim "${opts[$s]}"
fi
}
前提条件: 输出必须以“\n”分隔。
用法: 输出选择 [命令]
例子:
output_selection grep '.php$' foo.txt
这并不完全是您所要求的,因此您可以将其视为以 IMO 更方便的方式执行相同任务的合理建议 - 特别是当输出很大时。
答案2
假设文件名不包含空格,这将满足您的要求:
$ set -- $(grep -ilr mysql_connect * | tac)
$ echo $3
httpdocs/includes/config.php
$ echo $2
httpdocs/admin/db.php
$ echo $1
statistics/logs/error_log
您可以创建其他函数,而无需| tac
按正确的顺序打印它:
$ set -- $(grep -ilr mysql_connect *)
$ echo $1
httpdocs/includes/config.php
$ echo $2
httpdocs/admin/db.php
$ echo $3
statistics/logs/error_log