如何截断grep或ack返回的长匹配行


89

我想在通常行很长的HTML文件上运行ack或grep。我不想看到很长的线条反复缠绕。但是我确实想看到长线的那一部分包围与正则表达式匹配的字符串。如何使用Unix工具的任意组合获得此信息?


1
什么ack啊 当您不喜欢某些东西时使用的命令吗?像ack file_with_long_lines | grep pattern什么?:-)
Alok Singhal 2010年

6
@Alok ackack-grep在Debiangrep上称为)在类固醇上。它还具有--thpppt选项(不是在开玩笑)。 betterthangrep.com
ZoogieZork

谢谢。我今天学到了一些东西。
Alok Singhal 2010年

1
虽然该--thpppt功能有些争议,但主要优点似乎是您可以直接使用Perl正则表达式,而不必疯狂地使用,等[[:space:]]字符{,并且[-e-E开关改变了含义,而这种方式无法记住。
Evgeni Sergeev 2014年

Answers:


99

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

       -o,--only-matching
              仅显示匹配PATTERN的匹配线部分。

..或-c

       -c,--count
              抑制正常输出;而是打印匹配行数
              对于每个输入文件。使用-v,--invert-match选项(请参见
              下方),计算不匹配的行。

44
示例:grep -oE“。{0,20} mysearchstring。{0,20}” myfile
Renaud

14
您应该更改答案以添加-E选项(如@Renaud所示)(扩展模式选项),否则扩展上下文的建议模式将无法正常工作。
克里斯

也许没有必要,但是这里有一个例子: $ echo "eeeeeeeeeeeeeeeeeeeeqqqqqqqqqqqqqqqqqqqqMYSTRINGwwwwwwwwwwwwwwwwwwwwrrrrrrrrrrrrrrrrrrrrr" > fileonelongline.txt && grep -oE ".{0,20}MYSTRING.{0,20}" ./fileonelongline.txt 版画qqqqqqqqqqqqqqqqqqqqMYSTRINGwwwwwwwwwwwwwwwwwwww
Ulises Layera '18

这很好用;但值得注意的缺点是,例如使用时oE ".{0,20}mysearchstring.{0,20}",您会失去上下文对“原始”字符串的突出显示,因为整个事情都变成了搜索模式。希望找到一种在搜索结果周围保留一些非突出显示的上下文的方法,以使视觉扫描和结果解释更加容易。
亚伦·瓦伦丁

1
哦,这是解决使用-oE ".{0,x}foo.{0,x}"方法引起的突出显示问题的解决方案(x上下文的字符数在哪里)-append`| grep foo`到最后。适用于ack或grep解决方案。更多的解决方案也在这里:unix.stackexchange.com/questions/163726/...
亚伦Wallentine

44

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


8
如果匹配的部分不是前80个字符怎么办?
以太2010年

3
FWIW我附加| cut=c1-120到grep上,为我工作(尽管不知道如何剪切匹配的文本)
Jake Rayson

26
| cut=c1-120不适用于我,我需要做| cut -c1-120
肯·科克伦

1
我认为@edib在语法上是正确的| cut -c 1-100 stackoverflow.com/a/48954102/1815624
CrandellWS

1
@AndyLester:--no-wrap使用的选项怎么样$COLUMNS
naught101

25

您可以少用ack作为寻呼机来确认和截断长行:ack --pager="less -S" 这保留了长行,但将其留在一行而不是换行。要查看更多内容,请使用箭头键向左/向右滚动较少。

我为ack设置了以下别名来做到这一点:

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

2
请注意--pager,如果您始终想使用该命令,可以将该命令放在〜/ .ackrc文件中。
安迪·莱斯特

到目前为止,这听起来似乎是解决该问题的最佳解决方案,这让我很烦。我希望我知道如何使用ack
Brian Peterson

@BrianPetersonack几乎就像grep,在最常见的情况下更简单
Aaron Wallentine


2

摘自:http : //www.topbug.ne​​t/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个字符。


可行,但为我输出尾随的垃圾,就像这样:^ [[?62; 9; c。我没有尝试调试,因为@Jonah Braun的回答使我满意。
sondra.kinsey

1

这是我的工作:

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

在我的.bash_profile中,我覆盖了grep,以便它在tput rmam之前和tput smam之后自动运行,这将禁用包装,然后重新启用它。


这是一个很好的选择-除非实际匹配超出屏幕范围...
Xerus

1

在此处输入图片说明

在无法使用的特殊情况下-E,可以使用:

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

0

我将以下内容放入.bashrc

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

然后,您可以grepl在命令行中使用可用于的任何参数grep。使用箭头键查看较长线条的尾部。使用q戒烟。

说明:

  • grepl() {:定义一个新功能,该功能将在每个(新)bash控制台中可用。
  • $(which grep):获取的完整路径grep。(Ubuntu为其定义了一个别名,grep它等同于grep --color=auto。我们不希望使用该别名,而是原始别名grep。)
  • --color=always:对输出着色。(--color=auto由于grep检测到输出已放入管道中并且不会对其进行着色,因此别名起不起作用。)
  • $@:将所有赋予grepl函数的参数放在此处。
  • less:使用显示行 less
  • -R:显示颜色
  • S:不要长行
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.