Storing output of awk to an array and print it to a file with comma delimiters
I am trying to use bash to go through multiple directories (sims) and search for a given string, setting each index of an array to its relevant output, then print that output with comma delimiters for each value and adding a semicolon delimiter to separate each file. Effectively, this should give me a CSV that I can split twice in excel. All the important information is in field 3 each time it finds "Total Energy", which is found in the file named "output" in each directory.
With the set of directories that I am currently testing, each output file should have 2500 energies, but the code currently does not find that (vide infra).
Here is the code I have so far:
#/bin/bash/
saveIFS="$IFS"
#Step 1: Ask user for the range of sims they want
echo "What is the first sim?"
read simcount
echo "What is the last sim?"
read simend
#Step 2: Create the energy files with proper naming conventions and make sure they're empty
energies+="energies${simcount}-${simend}.csv"
fenergies+="final_energies${simcount}-${simend}.out"
touch $energies
touch $fenergies
< $energies
< $fenergies
#Step 3: Go through each directory, print all energies into proper files
while [ $simcount -le $simend ]; do
echo $simcount
cd $print'sim'$simcount # Change to the directory of each specified sim
energy=($(awk '/Total Energy/{ print $3 }' output)) # Print all energies from output into an array
echo ${#energy[@]}
fenergy=${energy[${#energy[@]}-1]} # Get the last energy in each file
cd ../ # Go up a directory
IFS="," # Change the Internal Field Separator (IFS) to a comma
echo "${energy[*]};" >> $energies # Expand the array of energies into an IFS-delimited list; print it into the new energies file
echo "$fenergy" >> $fenergies # Put the final energy of each sim on a new line in the new final energies file
((simcount++))
done
IFS="$saveIFS"
exit 0
This gives the following output:
$ e.sh
What is the first sim?
6
What is the last sim?
15
6
2500
7
1
8
1
9
1
10
1
11
1
12
1
13
1
14
1
15
1
Which means that the loop is finding all 2500 energies the first time around, but each subsequent time through the loop it does not split the output of awk into an array. A representative example of the output this puts in the new file denoted as $energies:
-271.2872230353,-271.3198859908,-271.4166545741,-271.5362409096,-271.6700236287,-271.8068505329,-271.9076587286,...;
-273.2853761106
-273.2855419371
...
-273.2856368361
-273.2857720402
-273.2859963834;
-271.2872230353
-271.3198859908
-271.4166545741
...
To clarify, the first iteration of the loop is successful and outputs the array onto one line with a semicolon separator. All following iterations do not get split into an array (or have an array length of 1) and seem to repeat thousands of times before moving onto the next directory.
I have searched around for a while now, and I cannot figure out why this would happen. I have also tried unsetting energies at the end of each iteration to no avail. So my specific question(s) is(are): why would splitting awk output into an array work the first time through the loop but not any subsequent times? Are there better/more efficient ways of going about this using bash that would be worth checking out?
bash shell-script array
New contributor
add a comment |
I am trying to use bash to go through multiple directories (sims) and search for a given string, setting each index of an array to its relevant output, then print that output with comma delimiters for each value and adding a semicolon delimiter to separate each file. Effectively, this should give me a CSV that I can split twice in excel. All the important information is in field 3 each time it finds "Total Energy", which is found in the file named "output" in each directory.
With the set of directories that I am currently testing, each output file should have 2500 energies, but the code currently does not find that (vide infra).
Here is the code I have so far:
#/bin/bash/
saveIFS="$IFS"
#Step 1: Ask user for the range of sims they want
echo "What is the first sim?"
read simcount
echo "What is the last sim?"
read simend
#Step 2: Create the energy files with proper naming conventions and make sure they're empty
energies+="energies${simcount}-${simend}.csv"
fenergies+="final_energies${simcount}-${simend}.out"
touch $energies
touch $fenergies
< $energies
< $fenergies
#Step 3: Go through each directory, print all energies into proper files
while [ $simcount -le $simend ]; do
echo $simcount
cd $print'sim'$simcount # Change to the directory of each specified sim
energy=($(awk '/Total Energy/{ print $3 }' output)) # Print all energies from output into an array
echo ${#energy[@]}
fenergy=${energy[${#energy[@]}-1]} # Get the last energy in each file
cd ../ # Go up a directory
IFS="," # Change the Internal Field Separator (IFS) to a comma
echo "${energy[*]};" >> $energies # Expand the array of energies into an IFS-delimited list; print it into the new energies file
echo "$fenergy" >> $fenergies # Put the final energy of each sim on a new line in the new final energies file
((simcount++))
done
IFS="$saveIFS"
exit 0
This gives the following output:
$ e.sh
What is the first sim?
6
What is the last sim?
15
6
2500
7
1
8
1
9
1
10
1
11
1
12
1
13
1
14
1
15
1
Which means that the loop is finding all 2500 energies the first time around, but each subsequent time through the loop it does not split the output of awk into an array. A representative example of the output this puts in the new file denoted as $energies:
-271.2872230353,-271.3198859908,-271.4166545741,-271.5362409096,-271.6700236287,-271.8068505329,-271.9076587286,...;
-273.2853761106
-273.2855419371
...
-273.2856368361
-273.2857720402
-273.2859963834;
-271.2872230353
-271.3198859908
-271.4166545741
...
To clarify, the first iteration of the loop is successful and outputs the array onto one line with a semicolon separator. All following iterations do not get split into an array (or have an array length of 1) and seem to repeat thousands of times before moving onto the next directory.
I have searched around for a while now, and I cannot figure out why this would happen. I have also tried unsetting energies at the end of each iteration to no avail. So my specific question(s) is(are): why would splitting awk output into an array work the first time through the loop but not any subsequent times? Are there better/more efficient ways of going about this using bash that would be worth checking out?
bash shell-script array
New contributor
add a comment |
I am trying to use bash to go through multiple directories (sims) and search for a given string, setting each index of an array to its relevant output, then print that output with comma delimiters for each value and adding a semicolon delimiter to separate each file. Effectively, this should give me a CSV that I can split twice in excel. All the important information is in field 3 each time it finds "Total Energy", which is found in the file named "output" in each directory.
With the set of directories that I am currently testing, each output file should have 2500 energies, but the code currently does not find that (vide infra).
Here is the code I have so far:
#/bin/bash/
saveIFS="$IFS"
#Step 1: Ask user for the range of sims they want
echo "What is the first sim?"
read simcount
echo "What is the last sim?"
read simend
#Step 2: Create the energy files with proper naming conventions and make sure they're empty
energies+="energies${simcount}-${simend}.csv"
fenergies+="final_energies${simcount}-${simend}.out"
touch $energies
touch $fenergies
< $energies
< $fenergies
#Step 3: Go through each directory, print all energies into proper files
while [ $simcount -le $simend ]; do
echo $simcount
cd $print'sim'$simcount # Change to the directory of each specified sim
energy=($(awk '/Total Energy/{ print $3 }' output)) # Print all energies from output into an array
echo ${#energy[@]}
fenergy=${energy[${#energy[@]}-1]} # Get the last energy in each file
cd ../ # Go up a directory
IFS="," # Change the Internal Field Separator (IFS) to a comma
echo "${energy[*]};" >> $energies # Expand the array of energies into an IFS-delimited list; print it into the new energies file
echo "$fenergy" >> $fenergies # Put the final energy of each sim on a new line in the new final energies file
((simcount++))
done
IFS="$saveIFS"
exit 0
This gives the following output:
$ e.sh
What is the first sim?
6
What is the last sim?
15
6
2500
7
1
8
1
9
1
10
1
11
1
12
1
13
1
14
1
15
1
Which means that the loop is finding all 2500 energies the first time around, but each subsequent time through the loop it does not split the output of awk into an array. A representative example of the output this puts in the new file denoted as $energies:
-271.2872230353,-271.3198859908,-271.4166545741,-271.5362409096,-271.6700236287,-271.8068505329,-271.9076587286,...;
-273.2853761106
-273.2855419371
...
-273.2856368361
-273.2857720402
-273.2859963834;
-271.2872230353
-271.3198859908
-271.4166545741
...
To clarify, the first iteration of the loop is successful and outputs the array onto one line with a semicolon separator. All following iterations do not get split into an array (or have an array length of 1) and seem to repeat thousands of times before moving onto the next directory.
I have searched around for a while now, and I cannot figure out why this would happen. I have also tried unsetting energies at the end of each iteration to no avail. So my specific question(s) is(are): why would splitting awk output into an array work the first time through the loop but not any subsequent times? Are there better/more efficient ways of going about this using bash that would be worth checking out?
bash shell-script array
New contributor
I am trying to use bash to go through multiple directories (sims) and search for a given string, setting each index of an array to its relevant output, then print that output with comma delimiters for each value and adding a semicolon delimiter to separate each file. Effectively, this should give me a CSV that I can split twice in excel. All the important information is in field 3 each time it finds "Total Energy", which is found in the file named "output" in each directory.
With the set of directories that I am currently testing, each output file should have 2500 energies, but the code currently does not find that (vide infra).
Here is the code I have so far:
#/bin/bash/
saveIFS="$IFS"
#Step 1: Ask user for the range of sims they want
echo "What is the first sim?"
read simcount
echo "What is the last sim?"
read simend
#Step 2: Create the energy files with proper naming conventions and make sure they're empty
energies+="energies${simcount}-${simend}.csv"
fenergies+="final_energies${simcount}-${simend}.out"
touch $energies
touch $fenergies
< $energies
< $fenergies
#Step 3: Go through each directory, print all energies into proper files
while [ $simcount -le $simend ]; do
echo $simcount
cd $print'sim'$simcount # Change to the directory of each specified sim
energy=($(awk '/Total Energy/{ print $3 }' output)) # Print all energies from output into an array
echo ${#energy[@]}
fenergy=${energy[${#energy[@]}-1]} # Get the last energy in each file
cd ../ # Go up a directory
IFS="," # Change the Internal Field Separator (IFS) to a comma
echo "${energy[*]};" >> $energies # Expand the array of energies into an IFS-delimited list; print it into the new energies file
echo "$fenergy" >> $fenergies # Put the final energy of each sim on a new line in the new final energies file
((simcount++))
done
IFS="$saveIFS"
exit 0
This gives the following output:
$ e.sh
What is the first sim?
6
What is the last sim?
15
6
2500
7
1
8
1
9
1
10
1
11
1
12
1
13
1
14
1
15
1
Which means that the loop is finding all 2500 energies the first time around, but each subsequent time through the loop it does not split the output of awk into an array. A representative example of the output this puts in the new file denoted as $energies:
-271.2872230353,-271.3198859908,-271.4166545741,-271.5362409096,-271.6700236287,-271.8068505329,-271.9076587286,...;
-273.2853761106
-273.2855419371
...
-273.2856368361
-273.2857720402
-273.2859963834;
-271.2872230353
-271.3198859908
-271.4166545741
...
To clarify, the first iteration of the loop is successful and outputs the array onto one line with a semicolon separator. All following iterations do not get split into an array (or have an array length of 1) and seem to repeat thousands of times before moving onto the next directory.
I have searched around for a while now, and I cannot figure out why this would happen. I have also tried unsetting energies at the end of each iteration to no avail. So my specific question(s) is(are): why would splitting awk output into an array work the first time through the loop but not any subsequent times? Are there better/more efficient ways of going about this using bash that would be worth checking out?
bash shell-script array
bash shell-script array
New contributor
New contributor
New contributor
asked 14 mins ago
user3334794user3334794
1
1
New contributor
New contributor
add a comment |
add a comment |
0
active
oldest
votes
Your Answer
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "106"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
user3334794 is a new contributor. Be nice, and check out our Code of Conduct.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f509125%2fstoring-output-of-awk-to-an-array-and-print-it-to-a-file-with-comma-delimiters%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
0
active
oldest
votes
0
active
oldest
votes
active
oldest
votes
active
oldest
votes
user3334794 is a new contributor. Be nice, and check out our Code of Conduct.
user3334794 is a new contributor. Be nice, and check out our Code of Conduct.
user3334794 is a new contributor. Be nice, and check out our Code of Conduct.
user3334794 is a new contributor. Be nice, and check out our Code of Conduct.
Thanks for contributing an answer to Unix & Linux Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f509125%2fstoring-output-of-awk-to-an-array-and-print-it-to-a-file-with-comma-delimiters%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown