Bash piping command output to summation loop

When I get into bash, I like it, but it seems that there are many subtleties that ultimately contribute a lot to the functionality, and not all, 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 is this not so ?:

 grep number some.txt | cut -d " " -f 1 | while read i; do (( total+=i )); done 

some.txt:

 1 number 2 number 50 number 

both for and while loops take 1, 2, and 50 separately, but the for loop shows that the shared variable is 53 at the end, while in the while loop code it remains unchanged. I know some fundamental knowledge that I lack, please help me.

I also do not understand the differences in pipelines, for example If I started

 grep number some.txt | cut -d " " -f 1 | while read i; echo "-> $i"; done 

I get the expected result

 -> 1 -> 2 -> 50 

But if it works like that

 while read i; echo "-> $i"; done <<< $(grep number some.txt | cut -d " " -f 1) 

then the output will change to

 -> 1 2 50 

This seems strange to me, since grep prints the result on separate lines. As if it werenโ€™t ambiguous if I had a file with numbers 1 2 3 on separate lines and I ran

 while read i; echo "-> $i"; done < someother.txt 

Then the output will be echoed in different lines, as expected in the previous example. I know for files and <for command exits, but why is there a difference in this line?

Anyway, I was hoping someone could shed some light on this, thanks for your time!

+5
source share
1 answer
 grep number some.txt | cut -d " " -f 1 | while read i; do (( total+=i )); done 

Each command in the pipeline runs in a subshell. This means that when you put the while read into the pipeline, any variable assignments are lost.

See: BashFAQ 024 - โ€œI set the variables in the loop that are in the pipeline. Why do they disappear after the loop ends? Or why do I collect data to read?

 while read i; echo "-> $i"; done <<< "$(grep number some.txt | cut -d " " -f 1)" 

To keep grep newlines, add double quotes. Otherwise, the result of $(...) is subject to word splitting, which collapses all spaces into single spaces.

+6
source

Source: https://habr.com/ru/post/1212132/


All Articles