How can I turn these instructions into a loop?

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP












0















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 :



  1. The name of the student as the name of the file;

  2. 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 ?










share|improve this question




























    0















    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 :



    1. The name of the student as the name of the file;

    2. 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 ?










    share|improve this question


























      0












      0








      0








      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 :



      1. The name of the student as the name of the file;

      2. 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 ?










      share|improve this question
















      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 :



      1. The name of the student as the name of the file;

      2. 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






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Jan 28 at 21:26







      Finalmix6

















      asked Jan 28 at 20:03









      Finalmix6Finalmix6

      32




      32




















          2 Answers
          2






          active

          oldest

          votes


















          1














          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





          share|improve this answer

























          • 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


















          1














          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.






          share|improve this answer

























          • Thank you for this version too ! I'll take a note of this.

            – Finalmix6
            Jan 28 at 20:38










          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
          );



          );













          draft saved

          draft discarded


















          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









          1














          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





          share|improve this answer

























          • 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















          1














          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





          share|improve this answer

























          • 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













          1












          1








          1







          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





          share|improve this answer















          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






          share|improve this answer














          share|improve this answer



          share|improve this answer








          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

















          • 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













          1














          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.






          share|improve this answer

























          • Thank you for this version too ! I'll take a note of this.

            – Finalmix6
            Jan 28 at 20:38















          1














          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.






          share|improve this answer

























          • Thank you for this version too ! I'll take a note of this.

            – Finalmix6
            Jan 28 at 20:38













          1












          1








          1







          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.






          share|improve this answer















          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.







          share|improve this answer














          share|improve this answer



          share|improve this answer








          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

















          • 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

















          draft saved

          draft discarded
















































          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.




          draft saved


          draft discarded














          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





















































          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






          Popular posts from this blog

          How to check contact read email or not when send email to Individual?

          Bahrain

          Postfix configuration issue with fips on centos 7; mailgun relay