How can I turn these instructions into a loop?
Clash Royale CLAN TAG#URR8PPP
So I have a subject folder which contains subjects such as :
- Geography
- Math
These subjects are files.
And each one of them contain the name of a student with his mark.
Sor for example it will be,
For Geography
- Mattew 15
- Elena 14
And Math :
- Matthew 10
- Elena 19
I also have a student folder which is empty for now.
And the purpose of this folder is to put inside of it :
- The name of the student as the name of the file;
- The marks of all subjets this student received.
So here is my code :
#### Subjects folder #####
GEOGRAPHY="/home/subject/geography"
MATH="/home/subject/math"
##### Registration student #####
studentMatthew="/home/student/Matthew"
Geo_Matthew=$(grep "Matthew" "$GEOGRAPHY" | cut -d' ' -f2) > "$studentMatthew"
Math_Matthew=$(grep "Matthew" "$MATH" | cut -d' ' -f2) > "$studentMatthew"
studentElena="/home/student/Elena"
Geo_Elena=$(grep "Elena" "$GEOGRAPHY" | cut -d' ' -f2) > "$studentElena"
Math_Elena=$(grep "Elena" "$MATH" | cut -d' ' -f2) > "$studentElena"
##### SHOW RESULT #####
echo "Geography" >> "$studentMatthew" "$Geo_Matthew"
echo "Math" >> "$studentMatthew" "$Geo_Matthew"
echo "Geography" >> "$studentElena" "$Geo_Elena"
echo "Math" >> "$studentElena" "$Math_Elena"
This works perfectly.
But it is not a very good practice to write it this way.
Because if for example I add another student let's say Patrick, I'll have to manually add his marks for both Geography and Math.
So it'll be :
##### Registration Patrick #####
studentPatrick="/home/student/Patrick"
Geo_Patrick=$(grep "Patrick" "$GEOGRAPHY" | cut -d' ' -f2) > "$studentPatrick"
Math_Patrick=$(grep "Patrick" "$MATH" | cut -d' ' -f2) > "$studentPatrick"
##### SHOW RESULT PATRICK #####
echo "Geography" >> "$studentPatrick" "$Geo_Patrick"
echo "Math" >> "$studentPatrick" "$Math_Patrick"
And it'll be redundant..
So I was wondering,
Is there a way to refactor this code into a loop? So if I add a new student, I won't have to manually write it again ?
shell-script scripting
add a comment |
So I have a subject folder which contains subjects such as :
- Geography
- Math
These subjects are files.
And each one of them contain the name of a student with his mark.
Sor for example it will be,
For Geography
- Mattew 15
- Elena 14
And Math :
- Matthew 10
- Elena 19
I also have a student folder which is empty for now.
And the purpose of this folder is to put inside of it :
- The name of the student as the name of the file;
- The marks of all subjets this student received.
So here is my code :
#### Subjects folder #####
GEOGRAPHY="/home/subject/geography"
MATH="/home/subject/math"
##### Registration student #####
studentMatthew="/home/student/Matthew"
Geo_Matthew=$(grep "Matthew" "$GEOGRAPHY" | cut -d' ' -f2) > "$studentMatthew"
Math_Matthew=$(grep "Matthew" "$MATH" | cut -d' ' -f2) > "$studentMatthew"
studentElena="/home/student/Elena"
Geo_Elena=$(grep "Elena" "$GEOGRAPHY" | cut -d' ' -f2) > "$studentElena"
Math_Elena=$(grep "Elena" "$MATH" | cut -d' ' -f2) > "$studentElena"
##### SHOW RESULT #####
echo "Geography" >> "$studentMatthew" "$Geo_Matthew"
echo "Math" >> "$studentMatthew" "$Geo_Matthew"
echo "Geography" >> "$studentElena" "$Geo_Elena"
echo "Math" >> "$studentElena" "$Math_Elena"
This works perfectly.
But it is not a very good practice to write it this way.
Because if for example I add another student let's say Patrick, I'll have to manually add his marks for both Geography and Math.
So it'll be :
##### Registration Patrick #####
studentPatrick="/home/student/Patrick"
Geo_Patrick=$(grep "Patrick" "$GEOGRAPHY" | cut -d' ' -f2) > "$studentPatrick"
Math_Patrick=$(grep "Patrick" "$MATH" | cut -d' ' -f2) > "$studentPatrick"
##### SHOW RESULT PATRICK #####
echo "Geography" >> "$studentPatrick" "$Geo_Patrick"
echo "Math" >> "$studentPatrick" "$Math_Patrick"
And it'll be redundant..
So I was wondering,
Is there a way to refactor this code into a loop? So if I add a new student, I won't have to manually write it again ?
shell-script scripting
add a comment |
So I have a subject folder which contains subjects such as :
- Geography
- Math
These subjects are files.
And each one of them contain the name of a student with his mark.
Sor for example it will be,
For Geography
- Mattew 15
- Elena 14
And Math :
- Matthew 10
- Elena 19
I also have a student folder which is empty for now.
And the purpose of this folder is to put inside of it :
- The name of the student as the name of the file;
- The marks of all subjets this student received.
So here is my code :
#### Subjects folder #####
GEOGRAPHY="/home/subject/geography"
MATH="/home/subject/math"
##### Registration student #####
studentMatthew="/home/student/Matthew"
Geo_Matthew=$(grep "Matthew" "$GEOGRAPHY" | cut -d' ' -f2) > "$studentMatthew"
Math_Matthew=$(grep "Matthew" "$MATH" | cut -d' ' -f2) > "$studentMatthew"
studentElena="/home/student/Elena"
Geo_Elena=$(grep "Elena" "$GEOGRAPHY" | cut -d' ' -f2) > "$studentElena"
Math_Elena=$(grep "Elena" "$MATH" | cut -d' ' -f2) > "$studentElena"
##### SHOW RESULT #####
echo "Geography" >> "$studentMatthew" "$Geo_Matthew"
echo "Math" >> "$studentMatthew" "$Geo_Matthew"
echo "Geography" >> "$studentElena" "$Geo_Elena"
echo "Math" >> "$studentElena" "$Math_Elena"
This works perfectly.
But it is not a very good practice to write it this way.
Because if for example I add another student let's say Patrick, I'll have to manually add his marks for both Geography and Math.
So it'll be :
##### Registration Patrick #####
studentPatrick="/home/student/Patrick"
Geo_Patrick=$(grep "Patrick" "$GEOGRAPHY" | cut -d' ' -f2) > "$studentPatrick"
Math_Patrick=$(grep "Patrick" "$MATH" | cut -d' ' -f2) > "$studentPatrick"
##### SHOW RESULT PATRICK #####
echo "Geography" >> "$studentPatrick" "$Geo_Patrick"
echo "Math" >> "$studentPatrick" "$Math_Patrick"
And it'll be redundant..
So I was wondering,
Is there a way to refactor this code into a loop? So if I add a new student, I won't have to manually write it again ?
shell-script scripting
So I have a subject folder which contains subjects such as :
- Geography
- Math
These subjects are files.
And each one of them contain the name of a student with his mark.
Sor for example it will be,
For Geography
- Mattew 15
- Elena 14
And Math :
- Matthew 10
- Elena 19
I also have a student folder which is empty for now.
And the purpose of this folder is to put inside of it :
- The name of the student as the name of the file;
- The marks of all subjets this student received.
So here is my code :
#### Subjects folder #####
GEOGRAPHY="/home/subject/geography"
MATH="/home/subject/math"
##### Registration student #####
studentMatthew="/home/student/Matthew"
Geo_Matthew=$(grep "Matthew" "$GEOGRAPHY" | cut -d' ' -f2) > "$studentMatthew"
Math_Matthew=$(grep "Matthew" "$MATH" | cut -d' ' -f2) > "$studentMatthew"
studentElena="/home/student/Elena"
Geo_Elena=$(grep "Elena" "$GEOGRAPHY" | cut -d' ' -f2) > "$studentElena"
Math_Elena=$(grep "Elena" "$MATH" | cut -d' ' -f2) > "$studentElena"
##### SHOW RESULT #####
echo "Geography" >> "$studentMatthew" "$Geo_Matthew"
echo "Math" >> "$studentMatthew" "$Geo_Matthew"
echo "Geography" >> "$studentElena" "$Geo_Elena"
echo "Math" >> "$studentElena" "$Math_Elena"
This works perfectly.
But it is not a very good practice to write it this way.
Because if for example I add another student let's say Patrick, I'll have to manually add his marks for both Geography and Math.
So it'll be :
##### Registration Patrick #####
studentPatrick="/home/student/Patrick"
Geo_Patrick=$(grep "Patrick" "$GEOGRAPHY" | cut -d' ' -f2) > "$studentPatrick"
Math_Patrick=$(grep "Patrick" "$MATH" | cut -d' ' -f2) > "$studentPatrick"
##### SHOW RESULT PATRICK #####
echo "Geography" >> "$studentPatrick" "$Geo_Patrick"
echo "Math" >> "$studentPatrick" "$Math_Patrick"
And it'll be redundant..
So I was wondering,
Is there a way to refactor this code into a loop? So if I add a new student, I won't have to manually write it again ?
shell-script scripting
shell-script scripting
edited Jan 28 at 21:26
Finalmix6
asked Jan 28 at 20:03
Finalmix6Finalmix6
32
32
add a comment |
add a comment |
2 Answers
2
active
oldest
votes
for subjfile in /home/subject/*; do
awk -v subj="$(basename "$subjfile")" ' print subj, $2 >>"/home/student/" $1 ' "$subjfile"
done
This would iterate over all the subject files. The $subjfile
value would be something like /home/subject/Math
or /home/subject/Geography
etc., depending on what subjects were available.
The awk
program would open each of these files in turn and print the subject name (which is the "basename" of the pathname in $subjfile
, i.e. Math
or Geography
) followed by the mark in that subject (column 2 of the $subjfile
file).
This would be written to "/home/student/" $1
which is a pathname under /home/student
. The $1
is the first column of the $subjfile
file, which is the name of the student.
The code assumes that the student
directory is empty when the script starts running (or it will append to the files in there).
Running on the given data (including the misspelling of one of the names), this would create three files in /home/student
:
$ cat Elena
Geography 14
Math 19
$ cat Mattew
Geography 15
$ cat Matthew
Math 10
Note that the student names are picked from the files under /home/subject
and never hard-coded in the script. Also, the various subjects depends on what files are available in the /home/subject
directory.
Would you want to do this without involving awk
:
for subjfile in /home/subject/*; do
subject=$( basename "$subjfile" )
while read -r name marks; do
printf '%s %dn' "$subject" "$marks" >>"/home/student/$name"
done <"$subjfile"
done
Thank you very much ! It works !
– Finalmix6
Jan 28 at 20:38
The next step is to understand why it works... and what the failure conditions are, and why.
– Kusalananda
Jan 28 at 20:42
I understood the while loop, I'm looking forward now to understand your first method. I'll manage thank you very much.
– Finalmix6
Jan 28 at 20:43
add a comment |
Off the top of my head, you do something like this:
# loop over all files in the student directory
for studentfile in /home/student/*; do
# take just the name of the student (the file name without the path)
studentname="$studentfile##*/"
# uncomment the next line to clear the student files before populating them
# > "$studentfile"
# loop over all subject files
for subject in /home/subject/*; do
# again, remove the path
subject="$subject##*/"
grep "$studentname" "$subject" | cut -d' ' -f2 >> "$studentfile"
done
done
This assuming that the file names for the students and subjects are exactly the same as the labels used for them within the files and that there exists a file already for each student.
The $var##*/
expansion takes the value of $var
with the longest prefix matching */
removed, i.e. it leaves just the path. We need both for the student, since we use just Matthew
for the grep
but /home/student/Matthew
for the output redirection.
Note that your assignment Geo_Matthew=$(grep "Matthew" "$GEOGRAPHY" | cut -d' ' -f2) > "$studentMatthew"
has an extra redirection in it, the assignment doesn't create any output, so the redirection only truncates the file named in $studentMatthew
. You can just redirect the output of grep
to the file and remove the command substitution, the Geo_Matthew
variable, and the later echo
.
This would be better done with an awk or Perl script instead of a shell script, but the above is a possible way to arrange the commands you have in loops.
Thank you for this version too ! I'll take a note of this.
– Finalmix6
Jan 28 at 20:38
add a comment |
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
);
);
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%2f497282%2fhow-can-i-turn-these-instructions-into-a-loop%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
for subjfile in /home/subject/*; do
awk -v subj="$(basename "$subjfile")" ' print subj, $2 >>"/home/student/" $1 ' "$subjfile"
done
This would iterate over all the subject files. The $subjfile
value would be something like /home/subject/Math
or /home/subject/Geography
etc., depending on what subjects were available.
The awk
program would open each of these files in turn and print the subject name (which is the "basename" of the pathname in $subjfile
, i.e. Math
or Geography
) followed by the mark in that subject (column 2 of the $subjfile
file).
This would be written to "/home/student/" $1
which is a pathname under /home/student
. The $1
is the first column of the $subjfile
file, which is the name of the student.
The code assumes that the student
directory is empty when the script starts running (or it will append to the files in there).
Running on the given data (including the misspelling of one of the names), this would create three files in /home/student
:
$ cat Elena
Geography 14
Math 19
$ cat Mattew
Geography 15
$ cat Matthew
Math 10
Note that the student names are picked from the files under /home/subject
and never hard-coded in the script. Also, the various subjects depends on what files are available in the /home/subject
directory.
Would you want to do this without involving awk
:
for subjfile in /home/subject/*; do
subject=$( basename "$subjfile" )
while read -r name marks; do
printf '%s %dn' "$subject" "$marks" >>"/home/student/$name"
done <"$subjfile"
done
Thank you very much ! It works !
– Finalmix6
Jan 28 at 20:38
The next step is to understand why it works... and what the failure conditions are, and why.
– Kusalananda
Jan 28 at 20:42
I understood the while loop, I'm looking forward now to understand your first method. I'll manage thank you very much.
– Finalmix6
Jan 28 at 20:43
add a comment |
for subjfile in /home/subject/*; do
awk -v subj="$(basename "$subjfile")" ' print subj, $2 >>"/home/student/" $1 ' "$subjfile"
done
This would iterate over all the subject files. The $subjfile
value would be something like /home/subject/Math
or /home/subject/Geography
etc., depending on what subjects were available.
The awk
program would open each of these files in turn and print the subject name (which is the "basename" of the pathname in $subjfile
, i.e. Math
or Geography
) followed by the mark in that subject (column 2 of the $subjfile
file).
This would be written to "/home/student/" $1
which is a pathname under /home/student
. The $1
is the first column of the $subjfile
file, which is the name of the student.
The code assumes that the student
directory is empty when the script starts running (or it will append to the files in there).
Running on the given data (including the misspelling of one of the names), this would create three files in /home/student
:
$ cat Elena
Geography 14
Math 19
$ cat Mattew
Geography 15
$ cat Matthew
Math 10
Note that the student names are picked from the files under /home/subject
and never hard-coded in the script. Also, the various subjects depends on what files are available in the /home/subject
directory.
Would you want to do this without involving awk
:
for subjfile in /home/subject/*; do
subject=$( basename "$subjfile" )
while read -r name marks; do
printf '%s %dn' "$subject" "$marks" >>"/home/student/$name"
done <"$subjfile"
done
Thank you very much ! It works !
– Finalmix6
Jan 28 at 20:38
The next step is to understand why it works... and what the failure conditions are, and why.
– Kusalananda
Jan 28 at 20:42
I understood the while loop, I'm looking forward now to understand your first method. I'll manage thank you very much.
– Finalmix6
Jan 28 at 20:43
add a comment |
for subjfile in /home/subject/*; do
awk -v subj="$(basename "$subjfile")" ' print subj, $2 >>"/home/student/" $1 ' "$subjfile"
done
This would iterate over all the subject files. The $subjfile
value would be something like /home/subject/Math
or /home/subject/Geography
etc., depending on what subjects were available.
The awk
program would open each of these files in turn and print the subject name (which is the "basename" of the pathname in $subjfile
, i.e. Math
or Geography
) followed by the mark in that subject (column 2 of the $subjfile
file).
This would be written to "/home/student/" $1
which is a pathname under /home/student
. The $1
is the first column of the $subjfile
file, which is the name of the student.
The code assumes that the student
directory is empty when the script starts running (or it will append to the files in there).
Running on the given data (including the misspelling of one of the names), this would create three files in /home/student
:
$ cat Elena
Geography 14
Math 19
$ cat Mattew
Geography 15
$ cat Matthew
Math 10
Note that the student names are picked from the files under /home/subject
and never hard-coded in the script. Also, the various subjects depends on what files are available in the /home/subject
directory.
Would you want to do this without involving awk
:
for subjfile in /home/subject/*; do
subject=$( basename "$subjfile" )
while read -r name marks; do
printf '%s %dn' "$subject" "$marks" >>"/home/student/$name"
done <"$subjfile"
done
for subjfile in /home/subject/*; do
awk -v subj="$(basename "$subjfile")" ' print subj, $2 >>"/home/student/" $1 ' "$subjfile"
done
This would iterate over all the subject files. The $subjfile
value would be something like /home/subject/Math
or /home/subject/Geography
etc., depending on what subjects were available.
The awk
program would open each of these files in turn and print the subject name (which is the "basename" of the pathname in $subjfile
, i.e. Math
or Geography
) followed by the mark in that subject (column 2 of the $subjfile
file).
This would be written to "/home/student/" $1
which is a pathname under /home/student
. The $1
is the first column of the $subjfile
file, which is the name of the student.
The code assumes that the student
directory is empty when the script starts running (or it will append to the files in there).
Running on the given data (including the misspelling of one of the names), this would create three files in /home/student
:
$ cat Elena
Geography 14
Math 19
$ cat Mattew
Geography 15
$ cat Matthew
Math 10
Note that the student names are picked from the files under /home/subject
and never hard-coded in the script. Also, the various subjects depends on what files are available in the /home/subject
directory.
Would you want to do this without involving awk
:
for subjfile in /home/subject/*; do
subject=$( basename "$subjfile" )
while read -r name marks; do
printf '%s %dn' "$subject" "$marks" >>"/home/student/$name"
done <"$subjfile"
done
edited Jan 28 at 20:38
answered Jan 28 at 20:22
KusalanandaKusalananda
130k17247407
130k17247407
Thank you very much ! It works !
– Finalmix6
Jan 28 at 20:38
The next step is to understand why it works... and what the failure conditions are, and why.
– Kusalananda
Jan 28 at 20:42
I understood the while loop, I'm looking forward now to understand your first method. I'll manage thank you very much.
– Finalmix6
Jan 28 at 20:43
add a comment |
Thank you very much ! It works !
– Finalmix6
Jan 28 at 20:38
The next step is to understand why it works... and what the failure conditions are, and why.
– Kusalananda
Jan 28 at 20:42
I understood the while loop, I'm looking forward now to understand your first method. I'll manage thank you very much.
– Finalmix6
Jan 28 at 20:43
Thank you very much ! It works !
– Finalmix6
Jan 28 at 20:38
Thank you very much ! It works !
– Finalmix6
Jan 28 at 20:38
The next step is to understand why it works... and what the failure conditions are, and why.
– Kusalananda
Jan 28 at 20:42
The next step is to understand why it works... and what the failure conditions are, and why.
– Kusalananda
Jan 28 at 20:42
I understood the while loop, I'm looking forward now to understand your first method. I'll manage thank you very much.
– Finalmix6
Jan 28 at 20:43
I understood the while loop, I'm looking forward now to understand your first method. I'll manage thank you very much.
– Finalmix6
Jan 28 at 20:43
add a comment |
Off the top of my head, you do something like this:
# loop over all files in the student directory
for studentfile in /home/student/*; do
# take just the name of the student (the file name without the path)
studentname="$studentfile##*/"
# uncomment the next line to clear the student files before populating them
# > "$studentfile"
# loop over all subject files
for subject in /home/subject/*; do
# again, remove the path
subject="$subject##*/"
grep "$studentname" "$subject" | cut -d' ' -f2 >> "$studentfile"
done
done
This assuming that the file names for the students and subjects are exactly the same as the labels used for them within the files and that there exists a file already for each student.
The $var##*/
expansion takes the value of $var
with the longest prefix matching */
removed, i.e. it leaves just the path. We need both for the student, since we use just Matthew
for the grep
but /home/student/Matthew
for the output redirection.
Note that your assignment Geo_Matthew=$(grep "Matthew" "$GEOGRAPHY" | cut -d' ' -f2) > "$studentMatthew"
has an extra redirection in it, the assignment doesn't create any output, so the redirection only truncates the file named in $studentMatthew
. You can just redirect the output of grep
to the file and remove the command substitution, the Geo_Matthew
variable, and the later echo
.
This would be better done with an awk or Perl script instead of a shell script, but the above is a possible way to arrange the commands you have in loops.
Thank you for this version too ! I'll take a note of this.
– Finalmix6
Jan 28 at 20:38
add a comment |
Off the top of my head, you do something like this:
# loop over all files in the student directory
for studentfile in /home/student/*; do
# take just the name of the student (the file name without the path)
studentname="$studentfile##*/"
# uncomment the next line to clear the student files before populating them
# > "$studentfile"
# loop over all subject files
for subject in /home/subject/*; do
# again, remove the path
subject="$subject##*/"
grep "$studentname" "$subject" | cut -d' ' -f2 >> "$studentfile"
done
done
This assuming that the file names for the students and subjects are exactly the same as the labels used for them within the files and that there exists a file already for each student.
The $var##*/
expansion takes the value of $var
with the longest prefix matching */
removed, i.e. it leaves just the path. We need both for the student, since we use just Matthew
for the grep
but /home/student/Matthew
for the output redirection.
Note that your assignment Geo_Matthew=$(grep "Matthew" "$GEOGRAPHY" | cut -d' ' -f2) > "$studentMatthew"
has an extra redirection in it, the assignment doesn't create any output, so the redirection only truncates the file named in $studentMatthew
. You can just redirect the output of grep
to the file and remove the command substitution, the Geo_Matthew
variable, and the later echo
.
This would be better done with an awk or Perl script instead of a shell script, but the above is a possible way to arrange the commands you have in loops.
Thank you for this version too ! I'll take a note of this.
– Finalmix6
Jan 28 at 20:38
add a comment |
Off the top of my head, you do something like this:
# loop over all files in the student directory
for studentfile in /home/student/*; do
# take just the name of the student (the file name without the path)
studentname="$studentfile##*/"
# uncomment the next line to clear the student files before populating them
# > "$studentfile"
# loop over all subject files
for subject in /home/subject/*; do
# again, remove the path
subject="$subject##*/"
grep "$studentname" "$subject" | cut -d' ' -f2 >> "$studentfile"
done
done
This assuming that the file names for the students and subjects are exactly the same as the labels used for them within the files and that there exists a file already for each student.
The $var##*/
expansion takes the value of $var
with the longest prefix matching */
removed, i.e. it leaves just the path. We need both for the student, since we use just Matthew
for the grep
but /home/student/Matthew
for the output redirection.
Note that your assignment Geo_Matthew=$(grep "Matthew" "$GEOGRAPHY" | cut -d' ' -f2) > "$studentMatthew"
has an extra redirection in it, the assignment doesn't create any output, so the redirection only truncates the file named in $studentMatthew
. You can just redirect the output of grep
to the file and remove the command substitution, the Geo_Matthew
variable, and the later echo
.
This would be better done with an awk or Perl script instead of a shell script, but the above is a possible way to arrange the commands you have in loops.
Off the top of my head, you do something like this:
# loop over all files in the student directory
for studentfile in /home/student/*; do
# take just the name of the student (the file name without the path)
studentname="$studentfile##*/"
# uncomment the next line to clear the student files before populating them
# > "$studentfile"
# loop over all subject files
for subject in /home/subject/*; do
# again, remove the path
subject="$subject##*/"
grep "$studentname" "$subject" | cut -d' ' -f2 >> "$studentfile"
done
done
This assuming that the file names for the students and subjects are exactly the same as the labels used for them within the files and that there exists a file already for each student.
The $var##*/
expansion takes the value of $var
with the longest prefix matching */
removed, i.e. it leaves just the path. We need both for the student, since we use just Matthew
for the grep
but /home/student/Matthew
for the output redirection.
Note that your assignment Geo_Matthew=$(grep "Matthew" "$GEOGRAPHY" | cut -d' ' -f2) > "$studentMatthew"
has an extra redirection in it, the assignment doesn't create any output, so the redirection only truncates the file named in $studentMatthew
. You can just redirect the output of grep
to the file and remove the command substitution, the Geo_Matthew
variable, and the later echo
.
This would be better done with an awk or Perl script instead of a shell script, but the above is a possible way to arrange the commands you have in loops.
edited Jan 28 at 20:22
answered Jan 28 at 20:15
ilkkachuilkkachu
59k892166
59k892166
Thank you for this version too ! I'll take a note of this.
– Finalmix6
Jan 28 at 20:38
add a comment |
Thank you for this version too ! I'll take a note of this.
– Finalmix6
Jan 28 at 20:38
Thank you for this version too ! I'll take a note of this.
– Finalmix6
Jan 28 at 20:38
Thank you for this version too ! I'll take a note of this.
– Finalmix6
Jan 28 at 20:38
add a comment |
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%2f497282%2fhow-can-i-turn-these-instructions-into-a-loop%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