Move Lines Matching a Pattern from One File to Another

Move lines matching a pattern from one file to another

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.

how to pick specific lines based on pattern match from a file to another file

Answer 1:

egrep -A 1 "Envvi|Department" example_1.txt | awk -F: -v ORS="-" '/Value/ {print tolower($2)}' | sed -e 's/[" ]//g' -e 's/-$/\n/' -e 's/^/aws_/'

Input: cat example_1.txt

{
"Key": "Envvi",
"Value": "model"
},
{
"Key": "Department",
"Value": "Sys"
}
{
"Key": "Subdept",
"Value": "io"
}

OutPut:

something_model-sys

Adding further explanation:

1) egrep -A 1 "Envvi|Department" example_1.txt --> This searches for the required key values and prints that line and one line after the match(-A 1). Output of this first step alone will be as follows:

"Key": "Envvi",
"Value": "model"
--
"Key": "Department",
"Value": "Sys"

2) awk -F: -v ORS="-" '/Value/ {print tolower($2)}' --> This finds the Value pair from previous output and prints the 2nd field, using ":" as field separator. tolower() is used for lower case output. Following is the output of this step. Note that there's no newline at the end as ORS is set to "-".

 "model"- "sys"-

3) sed -e 's/[" ]//g' --> This part takes the input from previous step and removes any occurances of a double quotes and space. Following is the output after this step. Note that still there's no newline at the end.

model-sys-

4) 's/-$/\n/' --> This second part of sed takes the input from previous step and replaces the last occurance of hypen(-) at the end of the line with a newline. Following is the output after this step. Note that there's a newline now at the end.

model-sys

5) 's/^/aws_/' --> This final part of the sed takes the input from previous step and adds "aws_" string to the begining of the line.

aws_model-sys

Further improved/simplified version of Answer 1 that works in GNU AWK(using gsub):

egrep -A 1 "Envvi|Department" example_1.txt | awk -F: -v ORS="-" '/Value/ {gsub(/[" ]/,"",$2); print tolower($2)}' | sed -e 's/-$/\n/' -e 's/^/aws_/' 

Moving matching lines in a text file using sed

While you ask a sed solution I would propose to use awk for this.
Using an ugly nesting of a multitude of sed commands is not really recommended. Especially because you read your file twice.

Here is an awk

awk '/SRC_OUT_DIR/{t=$0;next}1;/DEFAULTS/{print t}' file

How does it work?

awk will read your file line by line. Per line, it will do the following three commands one after the other:

  1. /SRC_OUT_DIR/{t=$0;next}: if the line contains a substring matching SRC_OUT_DIR, then store the line in a variable t and move to the next line (don't execute 2 and 3)
  2. 1: default action: print the line
  3. /DEFAULTS/{print t}: if the current line contains the substring DEFAULTS, print the line stored in variable t

If you have multiple lines to move (this only moves downwards):

awk '/pattern1/ {t[1]=$0;next}
/pattern2/ {t[2]=$0;next}
/pattern3/ {t[3]=$0;next}
/target3/ { print t[3] }
1
/target1/ { print t[1] }
/target2/ { print t[2] }' file

note that pattern3 will be printed before target3.

Move lines from one .txt file to another

Using findstr you can print lines that don't match, too. So you can do it in several steps, psudocoded like this:

  • findstr pattern input > output
  • findstr /v pattern input > input-inverse
  • move /y input-inverse input

This should leave you with all lines matching pattern in output, and an input without those lines.

EDIT: Made the last step use move with an option to overwrite, so no need to remove the input before. I guess I (being mainly a Linux person) think of "rename" and "move" as the same thing, and took that overwrite for granted. So, thanks for the heads-up.

Print lines in one file matching patterns in another file

Try grep -Fwf file2 file1 > out

The -F option specifies plain string matching, so should be faster without having to engage the regex engine.

How do I match a pattern and then copy multiple lines?

Your existing awk matches correctly the rows from the ids' file, you now need to add a condition to print N lines ahead after reading the last field of the matching row. So we will set a variable p to the number of lines to print plus one (the current one), and decrease per row printing.

awk -F'/' 'NR==FNR{id[$0]; next} $1 in id{p=$6+1} p-->0{print}' file1 file2

or the same with last condition more "awkish" (by Ed Morton) and covering any possible extreme case of a huge file

awk -F'/' 'NR==FNR{id[$0]; next} $1 in id{p=$6+1} p&&p--' file1 file2

here the print condition is omitted, as it is the default action, and the condition is true again as long as decreasing p is positive.



Related Topics



Leave a reply



Submit