2

This question already has an answer here:

I have the string xyz which is a line in file1.txt, I want to copy all the lines after xyz in file1.txt to a new file file2.txt. How can I achieve this?

I know about cat command. But how to specify the starting line?

marked as duplicate by Kusalananda, don_crissti, Rui F Ribeiro, Thomas, Jeff Schaller Mar 10 at 13:15

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

  • 2
    Do you want to include that xyz line or exclude it from being copied ? Also, what happens if you have multiple lines matching xyz ? – don_crissti Mar 9 at 21:44
3

Using GNU sed

To copy all lines after xyz, try:

sed '0,/xyz/d' file1.txt >file2.txt

1,/xyz/ specifies a range of lines starting with the first and ending with the first occurrence of a line matching xyz. d tells sed to delete those lines.

Note: For BSD/MacOS sed, one can use sed '1,/xyz/d' file1.txt >file2.txt but this only works if the first appearance of xyz is in the second line or later. (Hat tip: kusalananda.)

Another approach, as suggested by don_crissti, should work for all sed:

{ printf %s\\n; cat file1.txt; } | sed '1,/xyz/d' >file2.txt

Example

Consider this test file:

$ cat file1.txt
a
b
xyz
c
d

Run our command:

$ sed '1,/xyz/d' file1.txt >file2.txt
$ cat file2.txt
c
d

Using awk

The same logic can used with awk:

awk 'NR==1,/xyz/{next} 1' file1.txt >file2.txt

NR==1,/xyz/{next} tells awk to skip over all lines from the first (NR==1) to the first line matching the regex xyz. 1 tells awk to print any remaining lines.

  • @John1024 What sed are you using there? – Kusalananda Mar 9 at 23:03
  • @Kusalananda sed --version returns (GNU sed) 4.4. – John1024 Mar 9 at 23:06
  • Plz note that your answer first said: sed '0,/xyz/d then sed '1,/xyz/d. Whcih one is correct? – user9371654 Mar 16 at 20:54
  • @user9371654 If you have GNU sed (Linux, Windows, etc), use sed '0,/xyz/d. If you have BSD sed (default MacOS), then use { printf %s\\n; cat file1.txt; } | sed '1,/xyz/d' >file2.txt. – John1024 Mar 16 at 22:14
2

With ed:

ed -s file.txt <<< $'/xyz/+1,$w file2.txt'

This sends one (ranged) command to ed: from the line after (+1) the one containing xyz until the end of the file ($), write those lines to file2.txt.

1

There is also csplit :

csplit -s file1.txt %xyz%1
0
$ sed -n '/xyz/,$p' file.txt > file2.txt

With -n we prevent sed to print every line. With $ means end of file end p stands for print line. So /xyz/$p means: If a line matches xyz print it until the end of the file.

  • This would also print the line matching xyz, not from the line after. – Kusalananda Mar 9 at 22:02

Not the answer you're looking for? Browse other questions tagged or ask your own question.