我经常会用很长的行来 grep 文件,从而导致一个匹配单词的输出相当于一页。
将输出限制为仅与终端宽度相同的字符的好方法是什么?
我意识到这意味着匹配的词可能不在队列中。但我仍然想要上下文,所以仅文件名是不可接受的。
答案1
考虑这个包装函数,它将任何参数传递给 grep,然后将输出剪切到 $COLUMNS (或 80,如果未设置 COLUMNS):
function grepcut() {
grep "$@" | cut -c1-${COLUMNS:-80}
}
像这样使用它:
$ grepcut sometext somefiles
或者
$ set | grepcut LS_COLORS
答案2
这是一种更复杂的方法,可以提供您可能更喜欢的输出。如果您通常搜索简单字符串(没有正则表达式特殊字符)并且不使用任何选项(或者至少使用相同的选项),那么它的效果最好每一个时间)。我的greptrim
脚本:
#!/bin/bash
case "$1" in
("")
echo "Usage: $0 string [files...]"
exit 2
;;
(-*)
echo "This script can't take options."
exit 2
;;
esac
read rows cols <<< $(stty size)
if [ "$cols" = "" ]
then
cols=80
fi
margin=$(( (cols-${#1}) / 2 ))
grep -o ".\{,$margin\}$1.\{,$margin\}" "${@:2}"
- 准备工作:检查是否存在非空字符串(模式)参数,并且它不是一个选项。
- 然后我们使用另一种方法来获取列数。1
- 从屏幕的宽度(列数)中减去字符串参数的宽度 (
${#1}
,然后除以二。这将计算字符串左侧和右侧可以拥有的字符数,并且该行仍然适合例如,对于 80 列屏幕上的 10 个字符的字符串,margin
将为 35(因为 35+10+35=80)。 - 最终的命令看起来有点像
grep -o "$@"
,但我们确实如此grep -o "$1" "${@:2}"
。"${@:2}"
是一个bashism,意思是,但从(如果有的话)"$@"
开始。$2
- 我们
$1
用.\{,$margin\}
- 例如.\{,35\}
- 前后包裹起来。这最多可匹配 35 个任何字符,因此,我们的模式总共最多可匹配 80 个字符,原始模式$1
位于中间。 -o
意味着只输出匹配的文本——所以我们每行最多输出 80 个字符。
我使用了这个示例文本:
Once upon a midnight dreary, while I pondered, weak and weary, Over many a quaint and curious volume of forgotten lore—
While I nodded, nearly napping, suddenly there came a tapping, As of some one gently rapping, rapping at my chamber door.
“’Tis some visitor,” I muttered, “tapping at my chamber door— Only this and nothing more.”
下面是在 80 列屏幕中运行的示例:
$ ./greptrim or raven.txt
r many a quaint and curious volume of forgotten lore—
ently rapping, rapping at my chamber door.
“’Tis some visitor,” I muttered, “tapping at my chamber d
oor— Only this and nothing more.”
请注意,字符串“or”在这节经文中出现了六次:“f或者得到”,“我或者e”、“做或者“, “访问或者“, “做或者”和“米或者e”。请注意,我们两次获得输入的第三行,因为“访问或者”和“做或者” 相距超过 39 个字符。
更多注意事项:
- 显然,该脚本可以扩展以处理选项。弄清楚哪个参数是模式以及哪个参数是文件名变得很棘手。
- 如果您总是想使用某些选项,例如
-i
,只需将其添加到grep
脚本中的命令中即可。 - 如果相加
-n
,则应减去 4 或 5cols
。 - 您可以使用比简单字符串更复杂的模式的脚本,但结果可能不令人满意,因为短正则表达式可以匹配长文本段(反之亦然),因此 的计算
margin
将是错误的,您可能会每行多于(或少于)80 个字符。 - 如果添加
-E
,则必须将边距正则表达式更改为.{,$margin}
(删除反斜杠)。 一个可选功能是将最后一行更改为
grep -o ".\{,$margin\}$1.\{,$margin\}" "${@:2}" | grep --color=auto "$1"
突出显示搜索字符串:
请注意,“遗忘”中的“或”与“门”中的“或”完全一致。对于
margin
从行首开始出现的字符数多于字符的字符串,通常会发生这种情况。
_______
1我是cols
这样的 ( read rows cols <<< $(stty size)
)
- 展示不同的做法,并且
- 因为我正在使用 Cygwin,但
tput
尚未安装,也COLUMNS
未设置。
它符合 POSIX 标准。