![将 grep 传输到 less,将 grep 命令显示为文件名](https://linux22.com/image/1548401/%E5%B0%86%20grep%20%E4%BC%A0%E8%BE%93%E5%88%B0%20less%EF%BC%8C%E5%B0%86%20grep%20%E5%91%BD%E4%BB%A4%E6%98%BE%E7%A4%BA%E4%B8%BA%E6%96%87%E4%BB%B6%E5%90%8D.png)
less -M
将显示文件名作为提示,如下所示:
1 asdf
test.txt lines 1-1/1 (END)
为了便于阅读,我喜欢将 grep 连接到 less。我可以让 less 将 grep 命令解释为其提示符的文件名吗?
通常只是:
grep asdf test.txt | less
:
1 asdf
lines 1-1/1 (END)
我想要:
grep asdf test.txt | less
:
1 asdf
grep asdf test.txt lines 1-1/1 (END)
我知道我可以将这一切包装在一个脚本中并使用参数来执行操作,$0
但并不想在这里重新发明轮子。
是否仅通过几个命令行技巧就可以实现这一点?
答案1
less
根本不知道管道另一端通过标准输入向其提供数据的东西是什么,除非有人大大复杂化代码以less
找到less
正在运行的进程组和该进程组中的其他进程,然后谁知道它们是如何组合在一起的(shell 知道这些信息但可能不会提供)。
通过阅读,less(1)
你可能会发现-P
可以自定义提示的选项
$ echo hi | less -P '?f%f:Standard input'
hi
Standard input
所以理论上如果我们可以Standard input
用当前的 shell 管道替换位...让我们看看运行set
时是什么...less
$ function less { set > whatisset; command less "$@"; }
$ echo foo | less
foo
$ egrep 'echo|foo' whatisset
$
因此,对于 没有什么明显的用途mksh
,因为echo
或foo
(相当于grep
)不会出现在 shell 环境中的任何地方(对于zsh
和 哦哇bash
在 Linux 上也是一样的,曾经用设置轰炸环境,但又是同样的故事)。实际上,zsh
我们可以使用一个preexec
函数来使命令行可用:
$ zsh
% function preexec { shift; SHORT=$1; }
% function less { set > whatisset; command less "$@"; }
% echo foo | less
foo
% grep SHORT whatisset
SHORT='echo foo | less'
%
所以可以做类似的事情
% less() { =less -P '?f%f:'${SHORT%% | less} "$@"; }
% echo hi|less
hi
echo hi
答案2
我违背了自己的意愿,写了一个小脚本来实现这一点。虽然不太美观,但很实用,而且还不错,因为只有几行代码。我们一直在改进。
#!/bin/bash
# store all args as string
allargs="$*"
# create temp file named as grep command
TMPFILE=$(mktemp -q "$allargs")
# run grep command
$* --color=always > "$TMPFILE" # --color=always with less -r will highlight results in less
# show results file in less
less -Mr "$TMPFILE"
# delete the temp file
rm -f -- "$TMPFILE"
以 身份运行./scriptname grep <opts> <regex> <file(s)>
。
缺点:如果file
是(在当前目录中搜索所有内容),那么它们将被扩展并作为文件名的一部分,这会违背目的,因为它会将命令推离屏幕(非常长的文件名)。除非有办法在?*
中水平滚动文件名。less