Input file1 is:

dog 123 4335
cat 13123 23424 
deer 2131 213132
bear 2313 21313

I give the match the pattern from in other file ( like dog 123 4335 from file2).

I match the pattern of the line is dog 123 4335 and after printing all lines without match line my output is:

cat 13123 23424
deer 2131 213132
bear 2313 21313

If only use without address of line only use the pattern, for example 1s how to match and print the lines?

  • Can other file contain just a single pattern to search for, or one per line, and start searching at whichever line is found first in the searched file? Sep 14, 2016 at 12:52

12 Answers 12


In practice, I'd probably use Aet3miirah's answer most of the time, and alexey's answer is wonderful for navigating through the lines (also, it works with less). OTOH, I really like another approach (which is kind of the reversed Gilles' answer):

sed -n '/dog 123 4335/,$p'

When called with the -n flag, sed does not print by default the lines it processes anymore. Then we use a 2-address form that says to apply a command from the line matching /dog 123 4335/ until the end of the file (represented by $). The command in question is p, which prints the current line. So, this means "print all lines from the one matching /dog 123 4335/ until the end."

  • 6
    That prints the dog line though which is not wanted here. Jun 10, 2015 at 9:49
  • 4
    This looks like the best answer (and works for my own case) but would need to be adapted to skip the matched line as well. Mar 14, 2016 at 7:17
  • 4
    sed -n '/dog 123 4335/,$p' | sed '1d' will remove the dog line
    – Kemin Zhou
    Jul 2, 2018 at 5:26
  • 6
    sed -n '/dog 123 4335/,$p' | tail -n +2 will remove the match as well
    – gilad905
    Oct 24, 2018 at 13:01
  • 2
    Quick note: -n for don't-print-processed-lines, /pattern/ inside forward-slash /, $ for end, p for print May 4, 2021 at 7:08

If you have a reasonably short file grep alone might work:

grep -A5000 -m1 -e 'dog 123 4335' animals.txt

5000 is just my guess at "reasonably short", as grep finds the first match and outputs it together with the next 5000 lines (the file doesn't need to have that many). If you don't want the match itself you'll need to cut it off, e.g.

grep -A5000 -m1 -e 'dog 123 4335' animals.txt | tail -n+2

If you do not want the first, but the last match as delimiter you could use this:

tac animals.txt | sed -e '/dog 123 4335/q' | tac

This line reads animals.txt in reverse order of lines and outputs up to and including the line with dog 123 4335 and then reverses again to restore proper order.

Again, if you don't need the match in the result, append tail. (You could also complicate the sed expression to discard its buffer before quitting.)

  • By my test, GNU grep 3.0 doesn't output more than 132 lines in after-context (regardless of specified value).
    – ruvim
    Aug 29, 2017 at 9:44
  • Mine seems to max out at 1000 lines. Doesn't work at all in OS X. But at least it's more comprehensible :)
    – rogerdpack
    Feb 2, 2022 at 22:00

Assuming you want to match the whole line with your pattern, with GNU sed, this works:

sed -n '/^dog 123 4335$/ { :a; n; p; ba; }' infile

Standard equivalent:

sed -ne '/^dog 123 4335$/{:a' -e 'n;p;ba' -e '}' infile

With the following input (infile):

cat 13123 23424 
deer 2131 213132
bear 2313 21313
dog 123 4335
cat 13123 23424 
deer 2131 213132
bear 2313 21313

The output is:

cat 13123 23424 
deer 2131 213132
bear 2313 21313


  • /^dog 123 4335$/ searches for the desired pattern.
  • :a; n; p; ba; is a loop that fetches a new line from input (n), prints it (p), and branches back to label a :a; ...; ba;.


Here's an answer that comes closer to your needs, i.e. pattern in file2, grepping from file1:

tail -n +$(( 1 + $(grep -m1 -n -f file2 file1 | cut -d: -f1) )) file1

The embedded grep and cut find the first line containing a pattern from file2, this line number plus one is passed on to tail, the plus one is there to skip the line with the pattern.

If you want to start from the last match instead of the first match it would be:

tail -n +$(( 1 + $(grep -n -f file2 file1 | tail -n1 | cut -d: -f1) )) file1

Note that not all versions of tail support the plus-notation.

  • 1
    This is the first example of the n and p commands in sed that I have seen that doesn't feel like taking sed too far. It seems (from my brief tests) that sed -n '/^dog 123 4335$/ { :a; p; n; ba; }' infile (with the p and n switched) successfully includes the line that matches as well. Apr 3, 2019 at 15:25
sed -e '1,/dog 123 4335/d' file1

If you need to read the pattern from a file, substitute it into the sed command. If the file contains a sed pattern:

sed -e "1,/$(cat file2)/d" file1

If the file contains a literal string to look for, quote all special characters. I assume the file contains a single line.

sed -e "1,/$(sed 's/[][\\\/^$.*]/\\&/g' file2)/d" file1

If you want the match to be the whole line, not just a substring, wrap the pattern in ^…$.

sed -e "1,/^$(sed 's/[][\\\/^$.*]/\\&/g' file2)\$/d" file1
  • 7
    That won't work if the pattern is on the first line. GNU sed has 0,/dog.../d for that. Jun 10, 2015 at 9:48

$ more +/"dog 123 4335" file1

  • 5
    It also works with less.
    – brandizzi
    May 26, 2015 at 13:40
  • 6
    clever on the terminal, but it doesn't actually work if you pipe it into something else like tac. Jul 2, 2015 at 6:25
  • i am using it like this , $ more +/"match my words" file1 >> file2
    – user45645
    Jul 7, 2015 at 17:38
  • 1
    Maybe + was replaced by -p in POSIX 7: pubs.opengroup.org/onlinepubs/9699919799/utilities/more.html but not yet implemented in util-linux 2.20.1. And this also prints skipping.. and some extra newlines (to stderr I expect, so might be fine). Sep 14, 2016 at 12:41
  • maybe things have changed since then? my comment got 3 upvotes so it may have been relevant at the time... Nov 4, 2017 at 16:42

With awk:

awk 'BEGIN {getline pattern < "other file"}
   NR == 1, $0 ~ pattern {next}; {print}' < "input file"

My answer for the question in the subject, without storing pattern in a second file. Here is my test file:

$ cat animals.txt 
cat 13123 23424 
deer 2131 213132
bear 2313 21313
dog 123 4335
cat 13123 23424 
deer 2131 213132
bear 2313 21313

GNU sed:

 $ sed '0,/^dog 123 4335$/d' animals.txt 
 cat 13123 23424 
 deer 2131 213132
 bear 2313 21313


$ perl -ne 'print unless 1.../^dog 123 4335$/' animals.txt
cat 13123 23424 
deer 2131 213132
bear 2313 21313

Perl variant with pattern in a file:

$ cat pattern.txt 
dog 123 4335
$ perl -ne 'BEGIN{chomp($p=(<STDIN>)[0])};print unless 1../$p/;' animals.txt < pattern.txt
cat 13123 23424 
deer 2131 213132
bear 2313 21313
  • May I ask what is 1... in the first Perl variant? How is it different from the second's 1..?
    – Artfaith
    Mar 5 at 11:10

One way using awk:

awk 'NR==FNR{a[$0];next}f;($0 in a){f=1}'  file2 file1

where file2 contains your search patterns. First, all the contents of file2 are stored in the array "a". When the file1 is processed, every line is checked against the array, and printed only if is not present.

  • I think the OP wants to output every line following the pattern.
    – Thor
    Nov 23, 2012 at 11:41
  • @Thor : thanks for pointing it out, updated it now...
    – Guru
    Nov 23, 2012 at 11:57
  • Nicely done :).
    – Thor
    Nov 23, 2012 at 13:04

If the input is an lseekable regular file:

With GNU grep:

{ grep  -xFm1 'dog 123 4335' >&2
  cat; } <infile 2>/dev/null >outfile

With sed:

{ sed -n '/^dog 123 4335$/q'
  cat; } <infile >outfile

A GNU grep called w/ the -m option will quit input at the match - and it will leave its (lseekable) input fd immediately after the point it found its last match. So calling grep w/ -m1 finds the first occurrence of a pattern in a file, and leaves the input offset at precisely the right place for cat to write everything following the pattern's first match in a file to stdout.

Even without a GNU grep you can do the exact same thing w/ a POSIX compatible sed - when sed quits it is specified to leave its input offset right where it does. GNU sed is not standards-compliant in this way, though, and so the above will likely not work w/ a GNU sed unless you call it with its -u switch.

  • note, the sed stream sharing demonstrated here is not specially (though, yes, the standard referenced does specifically example sed as a utility thus capable) of the free-form and conditionally cooperative workflow shown. notably, all standard utilities are meant and specified to thus cooperate and share cursor positions of input streams without failing the next reader any processing at all. grep -q should do this; quietly grep should return as soon as any match in input is found, and any remaining of input should not, by standard, be consumed by default.
    – mikeserv
    Oct 29, 2018 at 10:43

Wth ed:

ed -s file1 <<< '/dog 123 4335/+1,$p'

This sends one print command to ed in a here-string; the print command is limited in range to one after (+1) the dog 123 4335 match until the end of the file ($).

  • Probably the most universal answer here because ed is available on just about every Unix in existence.
    – Jack G
    Jul 8, 2020 at 14:35

If you don't mind the creation of a temporary file, and have csplit available, this works:

sh -c 'csplit -sf"$1_" "$1" "%^$(cat "$2")%+1" && cat "${1}_00"' sh file1 file2

Note file1 is the input file and file2 is the pattern file (as stated in the question).

The long form of the above command is:

sh -c 'csplit --quiet --prefix="$1_" "$1" "%^$(cat "$2")%+1" && cat "${1}_00"' sh file1 file2


csplit --quiet --prefix="file1_" "file1" "%^$(cat "file2")%+1" && cat "file1_00"

csplit without the prefix flag above would create the file xx00 (prefix being xx, and suffix being 00). With the flag above it creates the file file1_00. Without the quiet flag, it prints the output file size (size of the resulting file).


Since awk isn't expressly disallowed, here's my offering assuming 'cat' is the match.

awk '$0 ~ /cat/ { vart = NR }{ arr[NR]=$0 } END { for (i = vart; i<=NR ; i++) print arr[i]  }' animals.txt

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .