# How to extract data from a file and construct a filename from one of the values

I'm trying to pull two values from a configuration file and write them to a new file. The hard part is that I want the name of the new file to be determined by one of the values in the input file.

The values I'm trying to pull are "Build_Version" and the four-letter acronym from the Docker name ("docker_Name"). For example, if the file says docker_Name='bcbs_pr-app-01', I want only the "bcbs". And I want to write them to a file with the build's name, such as bcbs_build.txt.

Here is an excerpt from the log file:

nonSSL_port=80  # FOR STAGING
Build_Type=prod
Build_Version=9.0.00.01_134143
docker_Name='bcbs-pr-app-01'


The desired file output is

bcbs
9.0.00.01_134143


I came up with a sed command that worked for pulling the values I wanted

sed -n -e '/Build_Version=/p' -e '/docker_Name=/p' environment-info.conf > build_version.txt


but this extracts the Build_Version= and docker_Name= lines in their entirety, and I want only the Build_Version and docker name values. And I still need to figure out how to name the file with the four-letter Docker name acronym (bcbs).

• You show an example input file with Build_Version followed by docker_Name, but an output with docker_Name followed by Build_Version. Do you always want the output in the order docker_Name, Build_Version, regardless of the order in the input file? – G-Man Mar 7 '16 at 16:13

## 5 Answers

That file looks like sh syntax. So, if that file is indeed a configuration file intended to be sourced in sh scripts, just do:

. ./environment-info.conf &&
printf '%s\n' "${docker_Name%%-*}" "$Build_Version" > "${docker_Name%%-*}_build.txt"  • Thank you! By adding a redirect using the variable "${docker_Name%%-}" , it worked perfectly! Here's what I did with your script: ./environment-info.conf && printf '%s\n' "${docker_Name%%-}" "$Build_Version" > ${docker_Name%%-*}.txt – Truth Seeker Mar 7 '16 at 17:18 • Sure, this is short and simple, but I'm surprised to see you recommending executing the contents of a data file without labeling the suggestion with warnings. – G-Man Mar 7 '16 at 17:27 1) alternating your sed, to a) remove first single quote of docker_Name, b) remove -pr-app-01' (including the last single quote), c) remove the <value>= part:  sed -n "/Build_Version=/s/.*=//p;/docker_Name=/s/.*=//;s/'//;s/-.*//p"  Where /match/s/pattern/replacement/ replaces pattern with replacement at a matching line. If replacement is an empty string, it is effectively removed. Note that I switched from single to double quotes to handle the single quote in your string and that you can use wildcards * . to match more complex strings and combine sed commands with a semi-colon. 2) We read in the two results as a BASH array: values=($( sed -n "/Build_Version=/s/.*=//p;/docker_Name=/s/.*=//;s/'//;s/-.*//p" file ) )


Where array=( value1 value2 value3 ) and $(do this command) 3) We use the array for our purposes, note that the counter starts at 0: echo${values[1]} > ${values[1]} echo${values[0]} >> ${values[1]}  Where we address an entry of an array via the array name and the intex of the entry ${array[intex]}.

Do you have to use sed for this? grep and perl can do what you need.

grep 'Build_Type\|docker_Name' environment-info.conf | perl -pe "s|docker_Name='(.*?)-.*|docker_Name=\1|" > build_version.txt

• if you're already using perl, you don't need grep as well. perl can do everything grep can do and more. Also this doesn't address the OP's requirement to name the output file based on the docker_Name variable in the input data. – cas Mar 7 '16 at 21:30

Using GNU sed:

sed -nr "s/^Build_Version=([^=]+)$/\1/p; s/^docker_Name='([^-]+).*/\1/p" file.txt  We are using capturing groups to get desired portions from the relevant lines. It has two parts: • s/^Build_Version=([^=]+)$/\1/ gets us 9.0.00.01_134143

• s/^docker_Name='([^-]+).*/\1/ gets us bcbs

To save the output to build_version.txt:

sed -nr "s/^Build_Version=([^=]+)$/\1/p; s/^docker_Name='([^-]+).*/\1/p" \ file.txt >build_version.txt  Example: % cat file.txt nonSSL_port=80 # FOR STAGING Build_Type=prod Build_Version=9.0.00.01_134143 docker_Name='bcbs-pr-app-01' % sed -nr "s/^Build_Version=([^=]+)$/\1/p; s/^docker_Name='([^-]+).*/\1/p" file.txt
9.0.00.01_134143
bcbs


You are looking for a way to name the file with four letters from docker name. That can be achieved by the below command, which will assign the four letters to a variable called File_Name.

File_Name=cat file | grep "docker_Name" | awk -F"'" '{print $2}' | awk -F'-' '{print$1}'


As mentioned in above answers below command will assign the docker_Name and build_version to an array called values:

values=($(sed -n "/docker_Name=/s/.*=//;s/'//;s/-.*//p;/Build_Version=/s/.*=//p" file))  We are accessing the array in reverse order to capture the output the way you want: for i in 1 0; do echo${values[$i]} >>$File_Name.txt; done


File will be ready with name you want and cat will display its content:

% cat bcbs.txt
bcbs
9.0.00.01_134143

• I believe that the OP wants the output in the order docker_Name, Build_Version, regardless of the order in the input file — not always the reverse of the order in the input file. – G-Man Mar 7 '16 at 17:30