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;
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
New contributor
add a comment |
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
New contributor
add a comment |
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
New contributor
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
bash shell-script
New contributor
New contributor
edited 9 hours ago
Rui F Ribeiro
42.1k1484142
42.1k1484142
New contributor
asked 10 hours ago
TuxKeyTuxKey
1
1
New contributor
New contributor
add a comment |
add a comment |
3 Answers
3
active
oldest
votes
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
add a comment |
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")"
add a comment |
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 bytecount
than with a loop.
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
);
);
TuxKey is a new contributor. Be nice, and check out our Code of Conduct.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%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
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
add a comment |
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
add a comment |
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
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
answered 9 hours ago
ilkkachuilkkachu
63.5k10104181
63.5k10104181
add a comment |
add a comment |
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")"
add a comment |
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")"
add a comment |
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")"
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")"
answered 9 hours ago
Jim L.Jim L.
1713
1713
add a comment |
add a comment |
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 bytecount
than with a loop.
add a comment |
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 bytecount
than with a loop.
add a comment |
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 bytecount
than with a loop.
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 bytecount
than with a loop.
answered 9 hours ago
bu5hmanbu5hman
1,356415
1,356415
add a comment |
add a comment |
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.
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.
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%2f512810%2fhow-does-this-work-for-loop-strips-variable-result%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
-bash, shell-script