How can I display the rest of a file starting from a matching line?
I want to display a line matching a search term and all the remaining lines in the file.
For example, if I use:
more text.txt | egrep show
it will only show the line that has "show" in it, while I would wish for something like a start
command:
more text.txt | start show
that will show all the lines after the first line that matches the search term.
However, it's not working on my Ubuntu. How can I install it or anything similar to it?
Solution 1:
If you don't particularly need grep, you could use sed
or awk
for this:
sed -n '/show/,$p' text.txt
awk '/show/ {display=1} display {print}' text.txt
-
sed
usually outputs all lines, but-n
prevents that./show/,$
is a line-range starting at the first line matching the regular expressionshow
and ending at the last line ($
). The print (p
) command prints that line-range. -
awk
uses sequences ofcondition { action }
pairs (usually on separate lines for readability), so/show/
is the condition that matches the regular expressionshow
anywhere in an input line, anddisplay=1
defines a variable nameddisplay
to1
. Obviously conditiondisplay
is a short form fordisplay != 0
, andprint
does what everyone expects, i.e.: print the input line.
Solution 2:
If your file is less than, say, 10000 lines, you can do this:
grep -A 10000 show text.txt
The -A
flag will show the line containing the search string (show
) and the next 10000 lines.
However, I played around with the -A
flag a bit, and I noticed grep
will intelligently combine the output, so you don't get 10001 lines for each time the string show
is found. So basically, it will show you the whole file once, starting from the line that contains show
. If your file contains more than 10000 lines, adjust the parameter appropriately.
You can use the alias
command to create your own custom command to achieve the same result.
EDIT: a slightly more elegant solution would be to use
grep show -A $(wc -l < text.txt) text.txt
which will use the actual length of the file as the -A
flag. This requires you to specify the file name twice. Unfortunately this will prevent the use of an alias, but you could write a shell function to do this.
Apparently, in this case you need to specify the search string first to avoid an error.
Solution 3:
awk '/show/,0' text.txt
Awk allows specifying a range condition-expression , condition-expression
, where the action-code is evaluated for each line between where the first condition returns true, until the second condition returns true.
By using constant false 0
as the second condition, the default action { print }
will run for the matching line and every line after that.
In case you want to define your start
command, awk
allows passing string variables, so here you go:
start() {
awk -v regex="$1" '$0 ~ regex, 0' "${@:2}"
}
$0 ~ regex
is used to match a string as if it were a regex. $0
in awk refers to the whole line. "${@:2}"
is all command arguments after the first one if there are any. That way, you can optionally specify files to start
, or else let it read from piped input.
Solution 4:
In Bash:
word="show"
e=0
while read line
do
[[ $line =~ "$word" ]] && e=1
[ $e -eq 1 ] && echo "$line"
done < text.txt
That can be added as a function to ~/.bashrc
like so:
grep2end () {
word="$1"
e=0
while read line
do
[[ $line =~ "$word" ]] && e=1
[ $e -eq 1 ] && echo "$line"
done < "$2"
}
and used like so:
grep2end "show" "text.txt"