I want to move lines matching certain pattern from file1 to file2. Analogous to operation cut and paste from one file to another in windows
Example
let's say I want to cut all lines containg bar
from file1 and paste it into newly created file2
Input:
file1
bla foo bla
bla bar bla
bla aaa bla
bla bar bla
bla foo bla
Desired output after processing:
file1
bla foo bla
bla aaa bla
bla foo bla
file2
bla bar bla
bla bar bla
What I have tried
grep
creates desired file2 but doesn't modify file1
grep 'bar' file1 > file2
sed -i
modifies desired file1 but doesn't create file2
sed -i '/bar/d' file1
If I execute both commands one after another, I get desired result. But here I am looking for a single line command out of curiosity and to make a script more concise.
Your help would be appreciated.
Use grep to select lines from text files that match simple patterns. Use find to find files and directories whose names match simple patterns. Use the output of one command as the command-line argument(s) to another command.
Use the mv command to move a file from one location to another. To move a file on a computer with a graphical interface, you open the folder where the file is currently located, and then open another window to the folder you want to move the file into.
3.5. 8.1 Pattern Matching. Any character that appears in a pattern, other than the special pattern characters described below, matches itself. The NUL character may not occur in a pattern. A backslash escapes the following character; the escaping backslash is discarded when matching.
The grep utility searches the given input files selecting lines which match one or more patterns. The type of patterns is controlled by the options specified. By default, a pattern matches an input line if any regular expression (RE) in the pattern matches the input line without its trailing newline.
You can use perl and select a different filehandle based in a match of a regular expression when printing:
perl -i.bak -ne 'BEGIN { open $oh, q|>|, pop or die } { print { m/bar/ ? $oh : q|ARGVOUT| } $_ }' file1 file2
It yields:
==> file1 <==
bla foo bla
bla aaa bla
bla foo bla
==> file2 <==
bla bar bla
bla bar bla
This might work for you (GNU sed):
sed -i -e '/bar/{w file2' -e 'd}' file1
An alternative:
sed -i -e '/bar/w file2' -e '//d' file1
To append to file2, write to a temporary file and use cat to append at the end of file in a bash script, or use:
sed -i -e '/bar/w tmpfile' -e '$e cat tmpfile >> file2 && rm tmpfile' -e '//d' file1
N.B. For the last solution, only one input file can be modified at a time.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With