how does this work ? for loop strips variable result Announcing the arrival of Valued Associate #679: Cesar Manara Planned maintenance scheduled April 17/18, 2019 at 00:00UTC (8:00pm US/Eastern) 2019 Community Moderator Election Results Why I closed the “Why is Kali so hard” questionWhy does my shell script choke on whitespace or other special characters?When is double-quoting necessary?How does this bash function work?Why does this incrementing for loop return a bad variable?Script to email all matching files in a directoryPrevent SIGINT from interrupting function call and child process(es) withinHow does this svn script work?How can I get this script to error exit based on result of for loop?Bash while loop read from colon-delimited list of paths using IFSbash script that incorporates content from a file as part of a commandBASH attempting to leave nested statements/loops/functionsWhy does this for loop ignore my variable?

Using et al. for a last / senior author rather than for a first author

Why am I getting the error "non-boolean type specified in a context where a condition is expected" for this request?

How to answer "Have you ever been terminated?"

Coloring maths inside a tcolorbox

Storing hydrofluoric acid before the invention of plastics

How to bypass password on Windows XP account?

Is there a problem creating Diff Backups every hour instead of Logs and DIffs?

Withdrew £2800, but only £2000 shows as withdrawn on online banking; what are my obligations?

Seeking colloquialism for “just because”

How to align text above triangle figure

List of Python versions

How to tell that you are a giant?

Single word antonym of "flightless"

What is a non-alternating simple group with big order, but relatively few conjugacy classes?

ListPlot join points by nearest neighbor rather than order

Sci-Fi book where patients in a coma ward all live in a subconscious world linked together

Denied boarding although I have proper visa and documentation. To whom should I make a complaint?

What does an IRS interview request entail when called in to verify expenses for a sole proprietor small business?

Why did the IBM 650 use bi-quinary?

When a candle burns, why does the top of wick glow if bottom of flame is hottest?

Is there a (better) way to access $wpdb results?

51k Euros annually for a family of 4 in Berlin: Is it enough?

Short Story with Cinderella as a Voo-doo Witch

Can an alien society believe that their star system is the universe?



how does this work ? for loop strips variable result



Announcing the arrival of Valued Associate #679: Cesar Manara
Planned maintenance scheduled April 17/18, 2019 at 00:00UTC (8:00pm US/Eastern)
2019 Community Moderator Election Results
Why I closed the “Why is Kali so hard” questionWhy does my shell script choke on whitespace or other special characters?When is double-quoting necessary?How does this bash function work?Why does this incrementing for loop return a bad variable?Script to email all matching files in a directoryPrevent SIGINT from interrupting function call and child process(es) withinHow does this svn script work?How can I get this script to error exit based on result of for loop?Bash while loop read from colon-delimited list of paths using IFSbash script that incorporates content from a file as part of a commandBASH attempting to leave nested statements/loops/functionsWhy does this for loop ignore my variable?



.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;








0















while learning bash/ksh from a book.
i came across an exercise that had a result i would love to understand.



When executing this script with bash -x to try to understand how it behaves (debugging) i noticed the line variable is number + filename. as this is the result of wc -c [file].
but as soon as the for loop sets the res variable it somehow strips the file name and only says res=23

(number result of wc -c) i can see it happening but don't really understand why ? i think i understand the for loop construct ..
for i in xxx do what ever.. don't 100% understand the break in this construct i do know it's to break out of a nested loop.



this is the exercise script:



if [ ! $# -eq 2 ] ;then
echo
echo "usage: $0 <location> <FileName>"
echo
exit 1
fi
TMPFILE=/tmp/count
line=$(find "$1" -name "$2" -type f -print | tee $TMPFILE | wc -l)
aant=$line
nr=0
som=0

while [ $nr -lt "$aant" ] ; do
nr=$(( nr +1 ))
bestand=$(head -$nr $TMPFILE | tail -1)
echo -n "$bestand"
line=$(wc -c "$bestand")

for woord in $line ; do
res=$woord
break
done
echo " $res"
som=$(( som + res ))
done

if [ "$aant" -eq 0 ] ; then
echo "No files found"
else
echo
echo "In totaal $aant files take $som bytes of space"
fi

rm $TMPFILE
exit 0









share|improve this question









New contributor




TuxKey is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.


























    0















    while learning bash/ksh from a book.
    i came across an exercise that had a result i would love to understand.



    When executing this script with bash -x to try to understand how it behaves (debugging) i noticed the line variable is number + filename. as this is the result of wc -c [file].
    but as soon as the for loop sets the res variable it somehow strips the file name and only says res=23

    (number result of wc -c) i can see it happening but don't really understand why ? i think i understand the for loop construct ..
    for i in xxx do what ever.. don't 100% understand the break in this construct i do know it's to break out of a nested loop.



    this is the exercise script:



    if [ ! $# -eq 2 ] ;then
    echo
    echo "usage: $0 <location> <FileName>"
    echo
    exit 1
    fi
    TMPFILE=/tmp/count
    line=$(find "$1" -name "$2" -type f -print | tee $TMPFILE | wc -l)
    aant=$line
    nr=0
    som=0

    while [ $nr -lt "$aant" ] ; do
    nr=$(( nr +1 ))
    bestand=$(head -$nr $TMPFILE | tail -1)
    echo -n "$bestand"
    line=$(wc -c "$bestand")

    for woord in $line ; do
    res=$woord
    break
    done
    echo " $res"
    som=$(( som + res ))
    done

    if [ "$aant" -eq 0 ] ; then
    echo "No files found"
    else
    echo
    echo "In totaal $aant files take $som bytes of space"
    fi

    rm $TMPFILE
    exit 0









    share|improve this question









    New contributor




    TuxKey is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
    Check out our Code of Conduct.






















      0












      0








      0








      while learning bash/ksh from a book.
      i came across an exercise that had a result i would love to understand.



      When executing this script with bash -x to try to understand how it behaves (debugging) i noticed the line variable is number + filename. as this is the result of wc -c [file].
      but as soon as the for loop sets the res variable it somehow strips the file name and only says res=23

      (number result of wc -c) i can see it happening but don't really understand why ? i think i understand the for loop construct ..
      for i in xxx do what ever.. don't 100% understand the break in this construct i do know it's to break out of a nested loop.



      this is the exercise script:



      if [ ! $# -eq 2 ] ;then
      echo
      echo "usage: $0 <location> <FileName>"
      echo
      exit 1
      fi
      TMPFILE=/tmp/count
      line=$(find "$1" -name "$2" -type f -print | tee $TMPFILE | wc -l)
      aant=$line
      nr=0
      som=0

      while [ $nr -lt "$aant" ] ; do
      nr=$(( nr +1 ))
      bestand=$(head -$nr $TMPFILE | tail -1)
      echo -n "$bestand"
      line=$(wc -c "$bestand")

      for woord in $line ; do
      res=$woord
      break
      done
      echo " $res"
      som=$(( som + res ))
      done

      if [ "$aant" -eq 0 ] ; then
      echo "No files found"
      else
      echo
      echo "In totaal $aant files take $som bytes of space"
      fi

      rm $TMPFILE
      exit 0









      share|improve this question









      New contributor




      TuxKey is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.












      while learning bash/ksh from a book.
      i came across an exercise that had a result i would love to understand.



      When executing this script with bash -x to try to understand how it behaves (debugging) i noticed the line variable is number + filename. as this is the result of wc -c [file].
      but as soon as the for loop sets the res variable it somehow strips the file name and only says res=23

      (number result of wc -c) i can see it happening but don't really understand why ? i think i understand the for loop construct ..
      for i in xxx do what ever.. don't 100% understand the break in this construct i do know it's to break out of a nested loop.



      this is the exercise script:



      if [ ! $# -eq 2 ] ;then
      echo
      echo "usage: $0 <location> <FileName>"
      echo
      exit 1
      fi
      TMPFILE=/tmp/count
      line=$(find "$1" -name "$2" -type f -print | tee $TMPFILE | wc -l)
      aant=$line
      nr=0
      som=0

      while [ $nr -lt "$aant" ] ; do
      nr=$(( nr +1 ))
      bestand=$(head -$nr $TMPFILE | tail -1)
      echo -n "$bestand"
      line=$(wc -c "$bestand")

      for woord in $line ; do
      res=$woord
      break
      done
      echo " $res"
      som=$(( som + res ))
      done

      if [ "$aant" -eq 0 ] ; then
      echo "No files found"
      else
      echo
      echo "In totaal $aant files take $som bytes of space"
      fi

      rm $TMPFILE
      exit 0






      bash shell-script






      share|improve this question









      New contributor




      TuxKey is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.











      share|improve this question









      New contributor




      TuxKey is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.









      share|improve this question




      share|improve this question








      edited 9 hours ago









      Rui F Ribeiro

      42.1k1484142




      42.1k1484142






      New contributor




      TuxKey is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.









      asked 10 hours ago









      TuxKeyTuxKey

      1




      1




      New contributor




      TuxKey is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.





      New contributor





      TuxKey is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.






      TuxKey is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.




















          3 Answers
          3






          active

          oldest

          votes


















          1














          In for word in $line, the contents of the variable line is split to words and then expanded for filename globs (see also these questions). The loop then runs once for each resulting value (or "word"). In this case though, there is only one iteration of the loop at most, since the break statement stops the loop from running. As a result, the value of res set on that first iteration of the loop remains, and the effect is the same as picking the first whitespace-separated word from line.



          There would be better ways of writing that, we could e.g. remove the filename with shell expansions. This would output 23:



          line='23 somefilename'
          res="$line%% *"
          echo "$res"


          Or, just have wc not output the filename to begin with, by redirecting the file to wc's stdin, instead of passing the filename to wc. Compare these two:



          $ wc -c foo.txt
          8 foo.txt
          $ wc -c < foo.txt
          8





          share|improve this answer






























            0














            If I understand your question correctly, the magic happens right here:



            for woord in $line ; do
            res=$woord
            break
            done


            To help you understand how that works, maybe considering this will help:



            for N in 1 2 3 4 5; do
            echo $N
            done
            echo "N is $N"


            Next, add the "break" statement and consider:



            for N in 1 2 3 4 5; do
            echo $N
            break
            done
            echo "N is $N"


            Can you describe what adding the break statement did to the for loop?



            In my opinion, the four lines of code I originally quoted could be pared down to just three:



            for res in $line ; do
            break
            done


            This is essentially a "kludgy" way of saying:



            res="$(awk 'print $1' <<< "$line")"





            share|improve this answer






























              0














              Check the man page for wc -c.



              It outputs bytecount filename into $line as a space separated list.



              The for $woord in $line loop reads the first variable (up till the first space) from $list, which is the bytecount and stores this in $res. Then instead of going on to read the next item in $list it hits the break instruction and exits the loop.



              As @ikkachu says, there are easier ways to get the bytecountthan with a loop.






              share|improve this answer























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



                );






                TuxKey is a new contributor. Be nice, and check out our Code of Conduct.









                draft saved

                draft discarded


















                StackExchange.ready(
                function ()
                StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f512810%2fhow-does-this-work-for-loop-strips-variable-result%23new-answer', 'question_page');

                );

                Post as a guest















                Required, but never shown

























                3 Answers
                3






                active

                oldest

                votes








                3 Answers
                3






                active

                oldest

                votes









                active

                oldest

                votes






                active

                oldest

                votes









                1














                In for word in $line, the contents of the variable line is split to words and then expanded for filename globs (see also these questions). The loop then runs once for each resulting value (or "word"). In this case though, there is only one iteration of the loop at most, since the break statement stops the loop from running. As a result, the value of res set on that first iteration of the loop remains, and the effect is the same as picking the first whitespace-separated word from line.



                There would be better ways of writing that, we could e.g. remove the filename with shell expansions. This would output 23:



                line='23 somefilename'
                res="$line%% *"
                echo "$res"


                Or, just have wc not output the filename to begin with, by redirecting the file to wc's stdin, instead of passing the filename to wc. Compare these two:



                $ wc -c foo.txt
                8 foo.txt
                $ wc -c < foo.txt
                8





                share|improve this answer



























                  1














                  In for word in $line, the contents of the variable line is split to words and then expanded for filename globs (see also these questions). The loop then runs once for each resulting value (or "word"). In this case though, there is only one iteration of the loop at most, since the break statement stops the loop from running. As a result, the value of res set on that first iteration of the loop remains, and the effect is the same as picking the first whitespace-separated word from line.



                  There would be better ways of writing that, we could e.g. remove the filename with shell expansions. This would output 23:



                  line='23 somefilename'
                  res="$line%% *"
                  echo "$res"


                  Or, just have wc not output the filename to begin with, by redirecting the file to wc's stdin, instead of passing the filename to wc. Compare these two:



                  $ wc -c foo.txt
                  8 foo.txt
                  $ wc -c < foo.txt
                  8





                  share|improve this answer

























                    1












                    1








                    1







                    In for word in $line, the contents of the variable line is split to words and then expanded for filename globs (see also these questions). The loop then runs once for each resulting value (or "word"). In this case though, there is only one iteration of the loop at most, since the break statement stops the loop from running. As a result, the value of res set on that first iteration of the loop remains, and the effect is the same as picking the first whitespace-separated word from line.



                    There would be better ways of writing that, we could e.g. remove the filename with shell expansions. This would output 23:



                    line='23 somefilename'
                    res="$line%% *"
                    echo "$res"


                    Or, just have wc not output the filename to begin with, by redirecting the file to wc's stdin, instead of passing the filename to wc. Compare these two:



                    $ wc -c foo.txt
                    8 foo.txt
                    $ wc -c < foo.txt
                    8





                    share|improve this answer













                    In for word in $line, the contents of the variable line is split to words and then expanded for filename globs (see also these questions). The loop then runs once for each resulting value (or "word"). In this case though, there is only one iteration of the loop at most, since the break statement stops the loop from running. As a result, the value of res set on that first iteration of the loop remains, and the effect is the same as picking the first whitespace-separated word from line.



                    There would be better ways of writing that, we could e.g. remove the filename with shell expansions. This would output 23:



                    line='23 somefilename'
                    res="$line%% *"
                    echo "$res"


                    Or, just have wc not output the filename to begin with, by redirecting the file to wc's stdin, instead of passing the filename to wc. Compare these two:



                    $ wc -c foo.txt
                    8 foo.txt
                    $ wc -c < foo.txt
                    8






                    share|improve this answer












                    share|improve this answer



                    share|improve this answer










                    answered 9 hours ago









                    ilkkachuilkkachu

                    63.5k10104181




                    63.5k10104181























                        0














                        If I understand your question correctly, the magic happens right here:



                        for woord in $line ; do
                        res=$woord
                        break
                        done


                        To help you understand how that works, maybe considering this will help:



                        for N in 1 2 3 4 5; do
                        echo $N
                        done
                        echo "N is $N"


                        Next, add the "break" statement and consider:



                        for N in 1 2 3 4 5; do
                        echo $N
                        break
                        done
                        echo "N is $N"


                        Can you describe what adding the break statement did to the for loop?



                        In my opinion, the four lines of code I originally quoted could be pared down to just three:



                        for res in $line ; do
                        break
                        done


                        This is essentially a "kludgy" way of saying:



                        res="$(awk 'print $1' <<< "$line")"





                        share|improve this answer



























                          0














                          If I understand your question correctly, the magic happens right here:



                          for woord in $line ; do
                          res=$woord
                          break
                          done


                          To help you understand how that works, maybe considering this will help:



                          for N in 1 2 3 4 5; do
                          echo $N
                          done
                          echo "N is $N"


                          Next, add the "break" statement and consider:



                          for N in 1 2 3 4 5; do
                          echo $N
                          break
                          done
                          echo "N is $N"


                          Can you describe what adding the break statement did to the for loop?



                          In my opinion, the four lines of code I originally quoted could be pared down to just three:



                          for res in $line ; do
                          break
                          done


                          This is essentially a "kludgy" way of saying:



                          res="$(awk 'print $1' <<< "$line")"





                          share|improve this answer

























                            0












                            0








                            0







                            If I understand your question correctly, the magic happens right here:



                            for woord in $line ; do
                            res=$woord
                            break
                            done


                            To help you understand how that works, maybe considering this will help:



                            for N in 1 2 3 4 5; do
                            echo $N
                            done
                            echo "N is $N"


                            Next, add the "break" statement and consider:



                            for N in 1 2 3 4 5; do
                            echo $N
                            break
                            done
                            echo "N is $N"


                            Can you describe what adding the break statement did to the for loop?



                            In my opinion, the four lines of code I originally quoted could be pared down to just three:



                            for res in $line ; do
                            break
                            done


                            This is essentially a "kludgy" way of saying:



                            res="$(awk 'print $1' <<< "$line")"





                            share|improve this answer













                            If I understand your question correctly, the magic happens right here:



                            for woord in $line ; do
                            res=$woord
                            break
                            done


                            To help you understand how that works, maybe considering this will help:



                            for N in 1 2 3 4 5; do
                            echo $N
                            done
                            echo "N is $N"


                            Next, add the "break" statement and consider:



                            for N in 1 2 3 4 5; do
                            echo $N
                            break
                            done
                            echo "N is $N"


                            Can you describe what adding the break statement did to the for loop?



                            In my opinion, the four lines of code I originally quoted could be pared down to just three:



                            for res in $line ; do
                            break
                            done


                            This is essentially a "kludgy" way of saying:



                            res="$(awk 'print $1' <<< "$line")"






                            share|improve this answer












                            share|improve this answer



                            share|improve this answer










                            answered 9 hours ago









                            Jim L.Jim L.

                            1713




                            1713





















                                0














                                Check the man page for wc -c.



                                It outputs bytecount filename into $line as a space separated list.



                                The for $woord in $line loop reads the first variable (up till the first space) from $list, which is the bytecount and stores this in $res. Then instead of going on to read the next item in $list it hits the break instruction and exits the loop.



                                As @ikkachu says, there are easier ways to get the bytecountthan with a loop.






                                share|improve this answer



























                                  0














                                  Check the man page for wc -c.



                                  It outputs bytecount filename into $line as a space separated list.



                                  The for $woord in $line loop reads the first variable (up till the first space) from $list, which is the bytecount and stores this in $res. Then instead of going on to read the next item in $list it hits the break instruction and exits the loop.



                                  As @ikkachu says, there are easier ways to get the bytecountthan with a loop.






                                  share|improve this answer

























                                    0












                                    0








                                    0







                                    Check the man page for wc -c.



                                    It outputs bytecount filename into $line as a space separated list.



                                    The for $woord in $line loop reads the first variable (up till the first space) from $list, which is the bytecount and stores this in $res. Then instead of going on to read the next item in $list it hits the break instruction and exits the loop.



                                    As @ikkachu says, there are easier ways to get the bytecountthan with a loop.






                                    share|improve this answer













                                    Check the man page for wc -c.



                                    It outputs bytecount filename into $line as a space separated list.



                                    The for $woord in $line loop reads the first variable (up till the first space) from $list, which is the bytecount and stores this in $res. Then instead of going on to read the next item in $list it hits the break instruction and exits the loop.



                                    As @ikkachu says, there are easier ways to get the bytecountthan with a loop.







                                    share|improve this answer












                                    share|improve this answer



                                    share|improve this answer










                                    answered 9 hours ago









                                    bu5hmanbu5hman

                                    1,356415




                                    1,356415




















                                        TuxKey is a new contributor. Be nice, and check out our Code of Conduct.









                                        draft saved

                                        draft discarded


















                                        TuxKey is a new contributor. Be nice, and check out our Code of Conduct.












                                        TuxKey is a new contributor. Be nice, and check out our Code of Conduct.











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




                                        draft saved


                                        draft discarded














                                        StackExchange.ready(
                                        function ()
                                        StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f512810%2fhow-does-this-work-for-loop-strips-variable-result%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







                                        -bash, shell-script

                                        Popular posts from this blog

                                        Creating 100m^2 grid automatically using QGIS?Creating grid constrained within polygon in QGIS?Createing polygon layer from point data using QGIS?Creating vector grid using QGIS?Creating grid polygons from coordinates using R or PythonCreating grid from spatio temporal point data?Creating fields in attributes table using other layers using QGISCreate .shp vector grid in QGISQGIS Creating 4km point grid within polygonsCreate a vector grid over a raster layerVector Grid Creates just one grid

                                        Nikolai Prilezhaev Bibliography References External links Navigation menuEarly Russian Organic Chemists and Their Legacy092774english translationRussian Biography

                                        How to link a C library to an Assembly library on Mac with clangHow do you set, clear, and toggle a single bit?Find (and kill) process locking port 3000 on MacWho is listening on a given TCP port on Mac OS X?How to start PostgreSQL server on Mac OS X?Compile assembler in nasm on mac osHow do I install pip on macOS or OS X?AFNetworking 2.0 “_NSURLSessionTransferSizeUnknown” linking error on Mac OS X 10.8C++ code for testing the Collatz conjecture faster than hand-written assembly - why?How to link a NASM code and GCC in Mac OS X?How to run x86 .asm on macOS Sierra