I have a text file containing the following lines:

This is the first line
Second line
I have a mac
Used to have windows
Comfortable with both

So now I want to grep "I have a mac", and move all the contents that follow, into a new file. How do I do this? Thanks!


Crop everything from the line that contain "I have a mac" to the end of the file and write the output to a new file:

sed -n '/I have a mac/,$ p' in-file > out-file

Remove everything from the line that contain "I have a mac" to the end of the file, make the changes in place of the file and create a backup copy of the original file:

sed '/I have a mac/,$ d' in-file -i.bak

Use a variable that contain the string that you are searching for and conditionally execute the above two commands:

SEARCH='I have a mac'
sed -n "/$SEARCH/,$ p" in-file > out-file && sed "/$SEARCH/,$ d" in-file -i.bak

Use grep to find (recursively) which file(s) contains the searched string and pass its name through pipe and xargs to the above commands (reference):

export SEARCH='I have a mac'
grep -lr "$SEARCH" | xargs -L1 -I {} sh -c 'sed -n "/$SEARCH/,$ p" {} > {}.out && sed "/$SEARCH/,$ d" {} -i.bak'

With grep you could use -A switch ( --> After Context) and | tail -n+2 to start output with the second line to skip the match.

grep -A $(wc -l < file) mac file | tail -n+2

But using sed is probably better for this case:

sed '1,/mac/d' file

This deletes everything from first line (1) until and including the matching line.

or you could use awk:

awk '{if(m)print}/mac/{m=1}' file

will print a line when variable m is true if(m)print}, which is set to 1/true after the first match /mac/{m=1}.

"Transfer" stdout from a command to a file can be done with redirection: > another_file

sed '1,/mac/d' file > another_file
awk '{if(m)print}/mac/{m=1}' file > another_file

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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