1

I have a text file with however many lines. One line is:

fixed_stringA = 123, fixed_stringB = 456

I have a second text file (again with however many lines). These 2 lines are in this order, in middle of the file:

found_value1=unknown1  
found_value2=unknown2

My goal is to modify these two lines second text file so that the it will now read:

found_value1=123  
found_value2=456

My goal is to do this on the command line without calling another script. The following code works, but I wonder if it can be shortened or improved:

value_variable=$(grep "fixed_stringA = [0-9]*, fixed_stringB = [0-9]*" first_file \
| sed -E 's/fixed_stringA = ([0-9]+), fixed_stringB = ([0-9]+)/\1,\2/'); \
value1=$(echo $value_variable | cut -d "," -f 1); \ 
value2=$(echo $value_variable | cut -d "," -f 2); \
sed -i -E "s/unknown1/$value1/" second_file.txt; \
sed -i -E "s/unknown2/$value2/" second_file.txt

2 Answers 2

2

I can get it down to these two lines:

values="$(sed -n -E 's/^.*fixed_stringA\s*=\s*([0-9]+)\s*,\s*fixed_stringB\s*=\s*([0-9]+).*$/\1,\2/p' first_file)"
sed -i -E -e "s/unknown1/${values%,*}/" -e "s/unknown2/${values#*,}/" second_file.txt

The first line uses sed with the -n flag so it suppresses regular output, and it finds the target line, extracts the numeric values into the capture groups \1 and \2 and turns them into 123,456 and prints that alone, saving that to the variable $values.

The next line does two substitutions in second_file.txt: everything before the comma in $values for unknown1 and everything after the comma for unknown2.

But I'm sure some awk export will be along any minute with a one-liner.

1

As a rule of thumb, using grep along with sed is almost always superfluous, because sed can filter by itself. In your case, you can use the p flag to the s command to print on a match only, then delete to suppress normal output:

sed -E 's/fixed_stringA = ([0-9]+), fixed_stringB = ([0-9]+)/\1,\2/p;d' first_file

Next, you would usually store the replacement strings in the hold space to apply them on the second file, but that will not work with -insplace editing, so we need a second sed command. Let's use the first one to generate that script for the second one:

sed -i.bak $(sed -E 's/fixed_stringA = ([0-9]+), fixed_stringB = ([0-9]+)/s_unknown1_\1_;s_unknown2_\2_/p;d' first_file) second_file

The inner script will produce the output s_unknown1_123_;s_unknown2_456_ which is the script needed to the second file.

Note: I use -i.bak to be compatible with other sed versions and to keep a copy in case I mess up the source 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.