How to truncate long matching lines returned by grep or ack

GrepUnixAck

Grep Problem Overview


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?

Grep Solutions


Solution 1 - Grep

You could use the grep option -o, possibly in combination with changing your pattern to ".{0,10}<original pattern>.{0,10}" in order to see some context around it:

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

..or -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.

Solution 2 - Grep

Pipe your results thru cut. I'm also considering adding a --cut switch so you could say --cut=80 and only get 80 columns.

Solution 3 - Grep

You could use less as a pager for ack and chop long lines: ack --pager="less -S" This retains the long line but leaves it on one line instead of wrapping. To see more of the line, scroll left/right in less with the arrow keys.

I have the following alias setup for ack to do this:

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

Solution 4 - Grep

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

In the unusual situation where you cannot use -E, use lowercase -e instead.

Explanation: enter image description here

Solution 5 - Grep

cut -c 1-100

gets characters from 1 to 100.

Solution 6 - Grep

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

The suggested approach ".{0,10}<original pattern>.{0,10}" is perfectly good except for that the highlighting color is often messed up. I've created a script with a similar output but the color is also preserved:

#!/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))}"

Assuming the script is saved as grepl, then grepl pattern file_with_long_lines should display the matching lines but with only 10 characters around the matching string.

Solution 7 - Grep

I put the following into my .bashrc:

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

You can then use grepl on the command line with any arguments that are available for grep. Use the arrow keys to see the tail of longer lines. Use q to quit.

Explanation:

  • grepl() {: Define a new function that will be available in every (new) bash console.
  • $(which grep): Get the full path of grep. (Ubuntu defines an alias for grep that is equivalent to grep --color=auto. We don't want that alias but the original grep.)
  • --color=always: Colorize the output. (--color=auto from the alias won't work since grep detects that the output is put into a pipe and won't color it then.)
  • $@: Put all arguments given to the grepl function here.
  • less: Display the lines using less
  • -R: Show colors
  • S: Don't break long lines

Solution 8 - Grep

Here's what I do:

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

In my .bash_profile, I override grep so that it automatically runs tput rmam before and tput smam after, which disabled wrapping and then re-enables it.

Solution 9 - Grep

The Silver Searcher (ag) supports its natively via the --width NUM option. It will replace the rest of longer lines by [...].

Example (truncate after 120 characters):

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

In ack3, a similar feature is planned but currently not implemented.

Solution 10 - Grep

ag can also take the regex trick, if you prefer it:

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestiondanView Question on Stackoverflow
Solution 1 - GrepEtherView Answer on Stackoverflow
Solution 2 - GrepAndy LesterView Answer on Stackoverflow
Solution 3 - GrepJonah BraunView Answer on Stackoverflow
Solution 4 - GrepJosh WitheeView Answer on Stackoverflow
Solution 5 - GrepedibView Answer on Stackoverflow
Solution 6 - GrepxuhdevView Answer on Stackoverflow
Solution 7 - Greppt1View Answer on Stackoverflow
Solution 8 - GrepognockocatenView Answer on Stackoverflow
Solution 9 - GrepPhilipp ClaßenView Answer on Stackoverflow
Solution 10 - GrepLuke MilesView Answer on Stackoverflow