How to truncate long matching lines returned by grep or ack

I want to run ack or grep on HTML files that often have very long lines. I don't want to see very long lines that wrap repeatedly. But I do want to see just that portion of a long line that surrounds a string that matches the regular expression. How can I get this using any combination of Unix tools?

51545 次浏览

您可以使用 grep 选项 -o,也许可以结合将模式更改为 ".{0,10}<original pattern>.{0,10}"来查看其周围的上下文:

-o, --only-matching
Show only the part of a matching line that matches PATTERN.

. . 或 -c:

-c, --count
Suppress normal output; instead print a count of matching  lines
for  each  input  file.  With the -v, --invert-match option (see
below), count non-matching lines.

通过 cut传送您的结果。我也在考虑添加一个 --cut开关,这样你就可以说 --cut=80,只有80列。

你可以使用较少的寻呼机,砍伐和削减长行: ack --pager="less -S"这保留了长行,但留在一行,而不是包装。若要查看更多行,请使用箭头键向左/向右滚动较少的内容。

我有以下的化名设置为 ack 这样做:

alias ick='ack -i --pager="less -R -S"'

摘自: http://www.topbug.net/blog/2016/08/18/truncate-long-matching-lines-of-grep-a-solution-that-preserves-color/

建议的方法 ".{0,10}<original pattern>.{0,10}"是非常好的,除了高亮的颜色经常混乱。我已经创建了一个具有类似输出的脚本,但颜色也保留了下来:

#!/bin/bash


# Usage:
#   grepl PATTERN [FILE]


# how many characters around the searching keyword should be shown?
context_length=10


# What is the length of the control character for the color before and after the
# matching string?
# This is mostly determined by the environmental variable GREP_COLORS.
control_length_before=$(($(echo a | grep --color=always a | cut -d a -f '1' | wc -c)-1))
control_length_after=$(($(echo a | grep --color=always a | cut -d a -f '2' | wc -c)-1))


grep -E --color=always "$1" $2 |
grep --color=none -oE \
".{0,$(($control_length_before + $context_length))}$1.{0,$(($control_length_after + $context_length))}"

假设脚本保存为 grepl,那么 grepl pattern file_with_long_lines应该显示匹配的行,但是在匹配的字符串周围只有10个字符。

cut -c 1-100

获取从1到100的字符。

我在我的 .bashrc中加入了以下内容:

grepl() {
$(which grep) --color=always $@ | less -RS
}

然后,您可以在命令行上使用 grepl和任何可用于 grep的参数。使用箭头键查看较长行的尾部。使用 q退出。

说明:

  • grepl() {: 定义一个在每个(新的) bash 控制台中都可用的新函数。
  • 获取 grep的完整路径。(Ubuntu 为 grep定义了一个等价于 grep --color=auto的别名。我们不想要那个化名,但原来的 grep。)
  • --color=always: 对输出进行着色。(来自别名的 --color=auto无法工作,因为 grep检测到输出被放入管道,然后不会给它上色。)
  • $@: 把给 grepl函数的所有参数放在这里。
  • less: Display the lines using less
  • 显示颜色
  • 不要破坏长队

我是这么做的:

function grep () {
tput rmam;
command grep "$@";
tput smam;
}

在我的。Bash _ profile,I 重写 grep,这样它会自动在前面运行 tput rmam,在后面运行 tput smam,这样就禁用了包装,然后重新启用它。

grep -oE ".\{0,10\}error.\{0,10\}" mylogfile.txt

在不常见的情况下,您不能使用 -E,而是使用小写的 -e

说明: enter image description here

如果你喜欢,ag也可以采用正则表达式的技巧:

ag --column -o ".{0,20}error.{0,20}"

Silver Searcher (ag) 通过 --width NUM选项支持其本机。它将用 [...]代替其余的长线。

示例(在120个字符后截断) :

 $ ag --width 120 '@patternfly'
...
1:{"version":3,"file":"react-icons.js","sources":["../../node_modules/@patternfly/ [...]

在 ack3中,一个 规划了类似的特征,但是目前还没有实现。