Getting into bash, I love it, but it seems there are lots of subtleties that end up making a big difference in functionality, and whatnot, anyway here is my question:
I know this works:
total=0
for i in $(grep number some.txt | cut -d " " -f 1); do
(( total+=i ))
done
But why doesn't this?:
grep number some.txt | cut -d " " -f 1 | while read i; do (( total+=i )); done
some.txt:
1 number
2 number
50 number
both the for and the while loop receive 1, 2, and 50 separately, but the for loop shows the total variable being 53 in the end, while in the while loop code, it just stays in zero. I know there's some fundamental knowledge I'm lacking here, please help me.
I also don't get the differences in piping, for example If I run
grep number some.txt | cut -d " " -f 1 | while read i; echo "-> $i"; done
I get the expected output
-> 1
-> 2
-> 50
But if run like so
while read i; echo "-> $i"; done <<< $(grep number some.txt | cut -d " " -f 1)
then the output changes to
-> 1 2 50
This seems weird to me since grep outputs the result in separate lines. As if this wasn't ambiguous, if I had a file with only numbers 1 2 3 in separate lines, and I ran
while read i; echo "-> $i"; done < someother.txt
Then the output would be printed by the echo in different lines, as expected in the previous example. I know < is for files and <<< for command outputs, but why does that line difference exist?
Anyways, I was hoping someone could shed some light on the matter, thank you for your time!
grep number some.txt | cut -d " " -f 1 | while read i; do (( total+=i )); done
Each command in a pipeline is run in a subshell. That means when you put the while read
loop in a pipeline any variable assignments are lost.
See: BashFAQ 024 - "I set variables in a loop that's in a pipeline. Why do they disappear after the loop terminates? Or, why can't I pipe data to read?"
while read i; echo "-> $i"; done <<< "$(grep number some.txt | cut -d " " -f 1)"
To preserve grep
's newlines, add double quotes. Otherwise the result of $(...)
is subject to word splitting which collapses all the whitespace into single spaces.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With