Bash Bug Fix: Reading a text file line by line and acting upon the lines












-3














Here's what my script looks like



#/bin/bash
touch input.txt
touch output.txt
seq -w 0 999 >>input.txt
input=$(cat input.txt)

for i in $input
do
if [ $(($i%2)) -eq 0 ]; then
echo $i "even" >> output.txt
else
echo $i "odd" >> output.txt
fi
done


Here's the result of running the script and viewing the output.txt file created



000 even
001 odd
002 even
003 odd
004 even
005 odd
006 even
007 odd


I would like the script to do this for all 1,000 lines of the script, but I get an error message on line 9 saying



./tester.sh: line 9: 008: value too great for base (error token is "008")


My end goal is for the script to add each number on a line, and then tell if the number is even or odd, outputting to output.txt for all 1000 lines of the file.



End goal output file:



000 even
001 odd
002 even
003 odd
...
505 even
506 odd
507 even
508 odd
...
998 even
999 odd


From 000 all the way to 999










share|improve this question
























  • See Bash FAQ 001 for the correct way to iterate through a file line by line.
    – chepner
    Nov 2 '18 at 15:57


















-3














Here's what my script looks like



#/bin/bash
touch input.txt
touch output.txt
seq -w 0 999 >>input.txt
input=$(cat input.txt)

for i in $input
do
if [ $(($i%2)) -eq 0 ]; then
echo $i "even" >> output.txt
else
echo $i "odd" >> output.txt
fi
done


Here's the result of running the script and viewing the output.txt file created



000 even
001 odd
002 even
003 odd
004 even
005 odd
006 even
007 odd


I would like the script to do this for all 1,000 lines of the script, but I get an error message on line 9 saying



./tester.sh: line 9: 008: value too great for base (error token is "008")


My end goal is for the script to add each number on a line, and then tell if the number is even or odd, outputting to output.txt for all 1000 lines of the file.



End goal output file:



000 even
001 odd
002 even
003 odd
...
505 even
506 odd
507 even
508 odd
...
998 even
999 odd


From 000 all the way to 999










share|improve this question
























  • See Bash FAQ 001 for the correct way to iterate through a file line by line.
    – chepner
    Nov 2 '18 at 15:57
















-3












-3








-3







Here's what my script looks like



#/bin/bash
touch input.txt
touch output.txt
seq -w 0 999 >>input.txt
input=$(cat input.txt)

for i in $input
do
if [ $(($i%2)) -eq 0 ]; then
echo $i "even" >> output.txt
else
echo $i "odd" >> output.txt
fi
done


Here's the result of running the script and viewing the output.txt file created



000 even
001 odd
002 even
003 odd
004 even
005 odd
006 even
007 odd


I would like the script to do this for all 1,000 lines of the script, but I get an error message on line 9 saying



./tester.sh: line 9: 008: value too great for base (error token is "008")


My end goal is for the script to add each number on a line, and then tell if the number is even or odd, outputting to output.txt for all 1000 lines of the file.



End goal output file:



000 even
001 odd
002 even
003 odd
...
505 even
506 odd
507 even
508 odd
...
998 even
999 odd


From 000 all the way to 999










share|improve this question















Here's what my script looks like



#/bin/bash
touch input.txt
touch output.txt
seq -w 0 999 >>input.txt
input=$(cat input.txt)

for i in $input
do
if [ $(($i%2)) -eq 0 ]; then
echo $i "even" >> output.txt
else
echo $i "odd" >> output.txt
fi
done


Here's the result of running the script and viewing the output.txt file created



000 even
001 odd
002 even
003 odd
004 even
005 odd
006 even
007 odd


I would like the script to do this for all 1,000 lines of the script, but I get an error message on line 9 saying



./tester.sh: line 9: 008: value too great for base (error token is "008")


My end goal is for the script to add each number on a line, and then tell if the number is even or odd, outputting to output.txt for all 1000 lines of the file.



End goal output file:



000 even
001 odd
002 even
003 odd
...
505 even
506 odd
507 even
508 odd
...
998 even
999 odd


From 000 all the way to 999







bash shell scripting sh






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 1 '18 at 21:44







bear443

















asked Nov 1 '18 at 17:34









bear443bear443

83




83












  • See Bash FAQ 001 for the correct way to iterate through a file line by line.
    – chepner
    Nov 2 '18 at 15:57




















  • See Bash FAQ 001 for the correct way to iterate through a file line by line.
    – chepner
    Nov 2 '18 at 15:57


















See Bash FAQ 001 for the correct way to iterate through a file line by line.
– chepner
Nov 2 '18 at 15:57






See Bash FAQ 001 for the correct way to iterate through a file line by line.
– chepner
Nov 2 '18 at 15:57














4 Answers
4






active

oldest

votes


















1














Use seq as seq and use printf to print your number in the format you like.

Bash arithmetic expansion interprets strings with leading zeros as octal numbers. You can force the number to be in 10th by prefixing it with 10# like (( 10#$i % 2)).



for i in $input
do
if [ $(( 10#$i % 2)) -eq 0 ]; then
echo $i "even" >> output.txt
else
echo $i "odd" >> output.txt
fi
done



  1. Keep in mind that arithmetic expansion (( .. )) can do comparisions. It's clear to if (( 10#$i % 2 == 0 )); then.

  2. I find printf "%03d" "$i" to be just clearer in this case.

  3. No need to touch a file before >>, should create the file aumatically (this can be turned off with some bash set -o option, but I haven't seen anyone use it).


  4. input=$(cat ...); for i in $input is just bad. Don't read lines with for

  5. I don't like temp files.


  6. How to read file line by line.


Your script is just:



seq 0 999 | xargs -i sh -c 'printf "%03d " "$1"; (( $1 % 2 == 0 )) && echo even || echo odd;'  >>output.txt


If you prefer while read:



seq 0 999 | while IFS= read -r num; do 
printf "%03d " "$num";
if (( num % 2 == 0 )); then
echo even
else
echo odd
fi
done >>output.txt


Or if you have to have your input.txt file containing 000n001n002n and so on it's time for a tee:



seq -w 0 999 | tee -a input.txt | while IFS= read -r num; do 
echo -n "$num "
if (( 10#$num % 2 == 0 )); then
echo even
else
echo odd
fi
done >>output.txt





share|improve this answer





















  • Thank you. This has gotten me the closest. However, in the end I need two files, an input file containing 000-999 and an output file with the '000-999 even/odd'. The output file has to be read from the input file, and this is where i'm struggling
    – bear443
    Nov 1 '18 at 22:19












  • The 4th snipped I added after edit (before your comment) does that.
    – Kamil Cuk
    Nov 1 '18 at 22:20










  • My only problem is I need the numbers in the like to be added before determined if even or odd. Look at line 507 number 506 in output.txt for example. This should be odd, as 5+0+6=11. How could I produce this?
    – bear443
    Nov 1 '18 at 22:34












  • So just sum the digits (we call them digits, not numbers....) and then check if they are odd or even. Something along the (( ${num:0:1} + ${num:1:1} + ${num:2:1} % 2 == 0)) check. 506 is an even number, the sum of the digits in 506 number is indeed an odd number.
    – Kamil Cuk
    Nov 1 '18 at 22:39












  • This is very close, though it appears every digit after 009 is being picked up as odd. Any reason as to why this may happen?
    – bear443
    Nov 1 '18 at 23:13





















1














This is a skeleton code for reading a text file line by line and acting upon the lines... Fill the missing part according to your own needs.



#!/bin/bash
{
while read -r line; do
if (( line % 2 == 0 )); then
# ...
else
# ...
fi
done < input.txt
} > output.txt


You may also apply pre-processing to the input file with <(cmd ...) notation:



#!/bin/bash
{
while read -r line; do
...
done < <(arbitrary-cmd input.txt | another-cmd ... )
} > output.txt


This form looks nicer but it spawns a "subshell" and makes it impossible for the code inside the while block to modify variables defined outside it, should you have any.



#!/bin/bash
{
arbitrary-cmd input.txt | another-cmd ... | while read -r line; do
...
done
} > output.txt





share|improve this answer























  • The command group isn't necessary, if the only command in it is the while loop (or if it contains just the one pipeline, as in the last example). Just use while ... done < input.txt > output.txt.
    – chepner
    Nov 2 '18 at 15:58












  • @chepner Right it isn't necessary. But I prefer to have it by default as it's handy for printing a header/footer etc
    – nodakai
    Nov 3 '18 at 8:09



















0














Your script could be something like



#!/bin/ksh
input=$(seq -w 0 999)
for i in $input
do
if [ $(($i%2)) -eq 0 ];then
echo $i "even" >> output.txt
else
echo $i "odd" >> output.txt
fi
done


then your output will be something like



000 even
001 odd
002 even
003 odd
004 even
005 odd
006 even
007 odd


Then you could grep "even" or "odd" and execute what you need or you could execute your command directly inside the if/else statement.






share|improve this answer























  • Do you know how I can do this for every single line all the way to 999, instead of stopping at 007? It seems to have a problem after line 9.
    – bear443
    Nov 1 '18 at 18:32












  • just edited, this works well
    – Valentino Di domenico
    Nov 2 '18 at 13:00



















0














This works too:



#!/bin/bash
for x in `seq -w 0 999`; do
if [ $((10#$x%2)) == 0 ]; then
echo $x even
else
echo $x odd
fi
done > output.txt





share|improve this answer





















    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    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: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    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%2fstackoverflow.com%2fquestions%2f53106466%2fbash-bug-fix-reading-a-text-file-line-by-line-and-acting-upon-the-lines%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    4 Answers
    4






    active

    oldest

    votes








    4 Answers
    4






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    1














    Use seq as seq and use printf to print your number in the format you like.

    Bash arithmetic expansion interprets strings with leading zeros as octal numbers. You can force the number to be in 10th by prefixing it with 10# like (( 10#$i % 2)).



    for i in $input
    do
    if [ $(( 10#$i % 2)) -eq 0 ]; then
    echo $i "even" >> output.txt
    else
    echo $i "odd" >> output.txt
    fi
    done



    1. Keep in mind that arithmetic expansion (( .. )) can do comparisions. It's clear to if (( 10#$i % 2 == 0 )); then.

    2. I find printf "%03d" "$i" to be just clearer in this case.

    3. No need to touch a file before >>, should create the file aumatically (this can be turned off with some bash set -o option, but I haven't seen anyone use it).


    4. input=$(cat ...); for i in $input is just bad. Don't read lines with for

    5. I don't like temp files.


    6. How to read file line by line.


    Your script is just:



    seq 0 999 | xargs -i sh -c 'printf "%03d " "$1"; (( $1 % 2 == 0 )) && echo even || echo odd;'  >>output.txt


    If you prefer while read:



    seq 0 999 | while IFS= read -r num; do 
    printf "%03d " "$num";
    if (( num % 2 == 0 )); then
    echo even
    else
    echo odd
    fi
    done >>output.txt


    Or if you have to have your input.txt file containing 000n001n002n and so on it's time for a tee:



    seq -w 0 999 | tee -a input.txt | while IFS= read -r num; do 
    echo -n "$num "
    if (( 10#$num % 2 == 0 )); then
    echo even
    else
    echo odd
    fi
    done >>output.txt





    share|improve this answer





















    • Thank you. This has gotten me the closest. However, in the end I need two files, an input file containing 000-999 and an output file with the '000-999 even/odd'. The output file has to be read from the input file, and this is where i'm struggling
      – bear443
      Nov 1 '18 at 22:19












    • The 4th snipped I added after edit (before your comment) does that.
      – Kamil Cuk
      Nov 1 '18 at 22:20










    • My only problem is I need the numbers in the like to be added before determined if even or odd. Look at line 507 number 506 in output.txt for example. This should be odd, as 5+0+6=11. How could I produce this?
      – bear443
      Nov 1 '18 at 22:34












    • So just sum the digits (we call them digits, not numbers....) and then check if they are odd or even. Something along the (( ${num:0:1} + ${num:1:1} + ${num:2:1} % 2 == 0)) check. 506 is an even number, the sum of the digits in 506 number is indeed an odd number.
      – Kamil Cuk
      Nov 1 '18 at 22:39












    • This is very close, though it appears every digit after 009 is being picked up as odd. Any reason as to why this may happen?
      – bear443
      Nov 1 '18 at 23:13


















    1














    Use seq as seq and use printf to print your number in the format you like.

    Bash arithmetic expansion interprets strings with leading zeros as octal numbers. You can force the number to be in 10th by prefixing it with 10# like (( 10#$i % 2)).



    for i in $input
    do
    if [ $(( 10#$i % 2)) -eq 0 ]; then
    echo $i "even" >> output.txt
    else
    echo $i "odd" >> output.txt
    fi
    done



    1. Keep in mind that arithmetic expansion (( .. )) can do comparisions. It's clear to if (( 10#$i % 2 == 0 )); then.

    2. I find printf "%03d" "$i" to be just clearer in this case.

    3. No need to touch a file before >>, should create the file aumatically (this can be turned off with some bash set -o option, but I haven't seen anyone use it).


    4. input=$(cat ...); for i in $input is just bad. Don't read lines with for

    5. I don't like temp files.


    6. How to read file line by line.


    Your script is just:



    seq 0 999 | xargs -i sh -c 'printf "%03d " "$1"; (( $1 % 2 == 0 )) && echo even || echo odd;'  >>output.txt


    If you prefer while read:



    seq 0 999 | while IFS= read -r num; do 
    printf "%03d " "$num";
    if (( num % 2 == 0 )); then
    echo even
    else
    echo odd
    fi
    done >>output.txt


    Or if you have to have your input.txt file containing 000n001n002n and so on it's time for a tee:



    seq -w 0 999 | tee -a input.txt | while IFS= read -r num; do 
    echo -n "$num "
    if (( 10#$num % 2 == 0 )); then
    echo even
    else
    echo odd
    fi
    done >>output.txt





    share|improve this answer





















    • Thank you. This has gotten me the closest. However, in the end I need two files, an input file containing 000-999 and an output file with the '000-999 even/odd'. The output file has to be read from the input file, and this is where i'm struggling
      – bear443
      Nov 1 '18 at 22:19












    • The 4th snipped I added after edit (before your comment) does that.
      – Kamil Cuk
      Nov 1 '18 at 22:20










    • My only problem is I need the numbers in the like to be added before determined if even or odd. Look at line 507 number 506 in output.txt for example. This should be odd, as 5+0+6=11. How could I produce this?
      – bear443
      Nov 1 '18 at 22:34












    • So just sum the digits (we call them digits, not numbers....) and then check if they are odd or even. Something along the (( ${num:0:1} + ${num:1:1} + ${num:2:1} % 2 == 0)) check. 506 is an even number, the sum of the digits in 506 number is indeed an odd number.
      – Kamil Cuk
      Nov 1 '18 at 22:39












    • This is very close, though it appears every digit after 009 is being picked up as odd. Any reason as to why this may happen?
      – bear443
      Nov 1 '18 at 23:13
















    1












    1








    1






    Use seq as seq and use printf to print your number in the format you like.

    Bash arithmetic expansion interprets strings with leading zeros as octal numbers. You can force the number to be in 10th by prefixing it with 10# like (( 10#$i % 2)).



    for i in $input
    do
    if [ $(( 10#$i % 2)) -eq 0 ]; then
    echo $i "even" >> output.txt
    else
    echo $i "odd" >> output.txt
    fi
    done



    1. Keep in mind that arithmetic expansion (( .. )) can do comparisions. It's clear to if (( 10#$i % 2 == 0 )); then.

    2. I find printf "%03d" "$i" to be just clearer in this case.

    3. No need to touch a file before >>, should create the file aumatically (this can be turned off with some bash set -o option, but I haven't seen anyone use it).


    4. input=$(cat ...); for i in $input is just bad. Don't read lines with for

    5. I don't like temp files.


    6. How to read file line by line.


    Your script is just:



    seq 0 999 | xargs -i sh -c 'printf "%03d " "$1"; (( $1 % 2 == 0 )) && echo even || echo odd;'  >>output.txt


    If you prefer while read:



    seq 0 999 | while IFS= read -r num; do 
    printf "%03d " "$num";
    if (( num % 2 == 0 )); then
    echo even
    else
    echo odd
    fi
    done >>output.txt


    Or if you have to have your input.txt file containing 000n001n002n and so on it's time for a tee:



    seq -w 0 999 | tee -a input.txt | while IFS= read -r num; do 
    echo -n "$num "
    if (( 10#$num % 2 == 0 )); then
    echo even
    else
    echo odd
    fi
    done >>output.txt





    share|improve this answer












    Use seq as seq and use printf to print your number in the format you like.

    Bash arithmetic expansion interprets strings with leading zeros as octal numbers. You can force the number to be in 10th by prefixing it with 10# like (( 10#$i % 2)).



    for i in $input
    do
    if [ $(( 10#$i % 2)) -eq 0 ]; then
    echo $i "even" >> output.txt
    else
    echo $i "odd" >> output.txt
    fi
    done



    1. Keep in mind that arithmetic expansion (( .. )) can do comparisions. It's clear to if (( 10#$i % 2 == 0 )); then.

    2. I find printf "%03d" "$i" to be just clearer in this case.

    3. No need to touch a file before >>, should create the file aumatically (this can be turned off with some bash set -o option, but I haven't seen anyone use it).


    4. input=$(cat ...); for i in $input is just bad. Don't read lines with for

    5. I don't like temp files.


    6. How to read file line by line.


    Your script is just:



    seq 0 999 | xargs -i sh -c 'printf "%03d " "$1"; (( $1 % 2 == 0 )) && echo even || echo odd;'  >>output.txt


    If you prefer while read:



    seq 0 999 | while IFS= read -r num; do 
    printf "%03d " "$num";
    if (( num % 2 == 0 )); then
    echo even
    else
    echo odd
    fi
    done >>output.txt


    Or if you have to have your input.txt file containing 000n001n002n and so on it's time for a tee:



    seq -w 0 999 | tee -a input.txt | while IFS= read -r num; do 
    echo -n "$num "
    if (( 10#$num % 2 == 0 )); then
    echo even
    else
    echo odd
    fi
    done >>output.txt






    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered Nov 1 '18 at 22:06









    Kamil CukKamil Cuk

    9,3701527




    9,3701527












    • Thank you. This has gotten me the closest. However, in the end I need two files, an input file containing 000-999 and an output file with the '000-999 even/odd'. The output file has to be read from the input file, and this is where i'm struggling
      – bear443
      Nov 1 '18 at 22:19












    • The 4th snipped I added after edit (before your comment) does that.
      – Kamil Cuk
      Nov 1 '18 at 22:20










    • My only problem is I need the numbers in the like to be added before determined if even or odd. Look at line 507 number 506 in output.txt for example. This should be odd, as 5+0+6=11. How could I produce this?
      – bear443
      Nov 1 '18 at 22:34












    • So just sum the digits (we call them digits, not numbers....) and then check if they are odd or even. Something along the (( ${num:0:1} + ${num:1:1} + ${num:2:1} % 2 == 0)) check. 506 is an even number, the sum of the digits in 506 number is indeed an odd number.
      – Kamil Cuk
      Nov 1 '18 at 22:39












    • This is very close, though it appears every digit after 009 is being picked up as odd. Any reason as to why this may happen?
      – bear443
      Nov 1 '18 at 23:13




















    • Thank you. This has gotten me the closest. However, in the end I need two files, an input file containing 000-999 and an output file with the '000-999 even/odd'. The output file has to be read from the input file, and this is where i'm struggling
      – bear443
      Nov 1 '18 at 22:19












    • The 4th snipped I added after edit (before your comment) does that.
      – Kamil Cuk
      Nov 1 '18 at 22:20










    • My only problem is I need the numbers in the like to be added before determined if even or odd. Look at line 507 number 506 in output.txt for example. This should be odd, as 5+0+6=11. How could I produce this?
      – bear443
      Nov 1 '18 at 22:34












    • So just sum the digits (we call them digits, not numbers....) and then check if they are odd or even. Something along the (( ${num:0:1} + ${num:1:1} + ${num:2:1} % 2 == 0)) check. 506 is an even number, the sum of the digits in 506 number is indeed an odd number.
      – Kamil Cuk
      Nov 1 '18 at 22:39












    • This is very close, though it appears every digit after 009 is being picked up as odd. Any reason as to why this may happen?
      – bear443
      Nov 1 '18 at 23:13


















    Thank you. This has gotten me the closest. However, in the end I need two files, an input file containing 000-999 and an output file with the '000-999 even/odd'. The output file has to be read from the input file, and this is where i'm struggling
    – bear443
    Nov 1 '18 at 22:19






    Thank you. This has gotten me the closest. However, in the end I need two files, an input file containing 000-999 and an output file with the '000-999 even/odd'. The output file has to be read from the input file, and this is where i'm struggling
    – bear443
    Nov 1 '18 at 22:19














    The 4th snipped I added after edit (before your comment) does that.
    – Kamil Cuk
    Nov 1 '18 at 22:20




    The 4th snipped I added after edit (before your comment) does that.
    – Kamil Cuk
    Nov 1 '18 at 22:20












    My only problem is I need the numbers in the like to be added before determined if even or odd. Look at line 507 number 506 in output.txt for example. This should be odd, as 5+0+6=11. How could I produce this?
    – bear443
    Nov 1 '18 at 22:34






    My only problem is I need the numbers in the like to be added before determined if even or odd. Look at line 507 number 506 in output.txt for example. This should be odd, as 5+0+6=11. How could I produce this?
    – bear443
    Nov 1 '18 at 22:34














    So just sum the digits (we call them digits, not numbers....) and then check if they are odd or even. Something along the (( ${num:0:1} + ${num:1:1} + ${num:2:1} % 2 == 0)) check. 506 is an even number, the sum of the digits in 506 number is indeed an odd number.
    – Kamil Cuk
    Nov 1 '18 at 22:39






    So just sum the digits (we call them digits, not numbers....) and then check if they are odd or even. Something along the (( ${num:0:1} + ${num:1:1} + ${num:2:1} % 2 == 0)) check. 506 is an even number, the sum of the digits in 506 number is indeed an odd number.
    – Kamil Cuk
    Nov 1 '18 at 22:39














    This is very close, though it appears every digit after 009 is being picked up as odd. Any reason as to why this may happen?
    – bear443
    Nov 1 '18 at 23:13






    This is very close, though it appears every digit after 009 is being picked up as odd. Any reason as to why this may happen?
    – bear443
    Nov 1 '18 at 23:13















    1














    This is a skeleton code for reading a text file line by line and acting upon the lines... Fill the missing part according to your own needs.



    #!/bin/bash
    {
    while read -r line; do
    if (( line % 2 == 0 )); then
    # ...
    else
    # ...
    fi
    done < input.txt
    } > output.txt


    You may also apply pre-processing to the input file with <(cmd ...) notation:



    #!/bin/bash
    {
    while read -r line; do
    ...
    done < <(arbitrary-cmd input.txt | another-cmd ... )
    } > output.txt


    This form looks nicer but it spawns a "subshell" and makes it impossible for the code inside the while block to modify variables defined outside it, should you have any.



    #!/bin/bash
    {
    arbitrary-cmd input.txt | another-cmd ... | while read -r line; do
    ...
    done
    } > output.txt





    share|improve this answer























    • The command group isn't necessary, if the only command in it is the while loop (or if it contains just the one pipeline, as in the last example). Just use while ... done < input.txt > output.txt.
      – chepner
      Nov 2 '18 at 15:58












    • @chepner Right it isn't necessary. But I prefer to have it by default as it's handy for printing a header/footer etc
      – nodakai
      Nov 3 '18 at 8:09
















    1














    This is a skeleton code for reading a text file line by line and acting upon the lines... Fill the missing part according to your own needs.



    #!/bin/bash
    {
    while read -r line; do
    if (( line % 2 == 0 )); then
    # ...
    else
    # ...
    fi
    done < input.txt
    } > output.txt


    You may also apply pre-processing to the input file with <(cmd ...) notation:



    #!/bin/bash
    {
    while read -r line; do
    ...
    done < <(arbitrary-cmd input.txt | another-cmd ... )
    } > output.txt


    This form looks nicer but it spawns a "subshell" and makes it impossible for the code inside the while block to modify variables defined outside it, should you have any.



    #!/bin/bash
    {
    arbitrary-cmd input.txt | another-cmd ... | while read -r line; do
    ...
    done
    } > output.txt





    share|improve this answer























    • The command group isn't necessary, if the only command in it is the while loop (or if it contains just the one pipeline, as in the last example). Just use while ... done < input.txt > output.txt.
      – chepner
      Nov 2 '18 at 15:58












    • @chepner Right it isn't necessary. But I prefer to have it by default as it's handy for printing a header/footer etc
      – nodakai
      Nov 3 '18 at 8:09














    1












    1








    1






    This is a skeleton code for reading a text file line by line and acting upon the lines... Fill the missing part according to your own needs.



    #!/bin/bash
    {
    while read -r line; do
    if (( line % 2 == 0 )); then
    # ...
    else
    # ...
    fi
    done < input.txt
    } > output.txt


    You may also apply pre-processing to the input file with <(cmd ...) notation:



    #!/bin/bash
    {
    while read -r line; do
    ...
    done < <(arbitrary-cmd input.txt | another-cmd ... )
    } > output.txt


    This form looks nicer but it spawns a "subshell" and makes it impossible for the code inside the while block to modify variables defined outside it, should you have any.



    #!/bin/bash
    {
    arbitrary-cmd input.txt | another-cmd ... | while read -r line; do
    ...
    done
    } > output.txt





    share|improve this answer














    This is a skeleton code for reading a text file line by line and acting upon the lines... Fill the missing part according to your own needs.



    #!/bin/bash
    {
    while read -r line; do
    if (( line % 2 == 0 )); then
    # ...
    else
    # ...
    fi
    done < input.txt
    } > output.txt


    You may also apply pre-processing to the input file with <(cmd ...) notation:



    #!/bin/bash
    {
    while read -r line; do
    ...
    done < <(arbitrary-cmd input.txt | another-cmd ... )
    } > output.txt


    This form looks nicer but it spawns a "subshell" and makes it impossible for the code inside the while block to modify variables defined outside it, should you have any.



    #!/bin/bash
    {
    arbitrary-cmd input.txt | another-cmd ... | while read -r line; do
    ...
    done
    } > output.txt






    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Nov 1 '18 at 18:04

























    answered Nov 1 '18 at 17:58









    nodakainodakai

    4,79321437




    4,79321437












    • The command group isn't necessary, if the only command in it is the while loop (or if it contains just the one pipeline, as in the last example). Just use while ... done < input.txt > output.txt.
      – chepner
      Nov 2 '18 at 15:58












    • @chepner Right it isn't necessary. But I prefer to have it by default as it's handy for printing a header/footer etc
      – nodakai
      Nov 3 '18 at 8:09


















    • The command group isn't necessary, if the only command in it is the while loop (or if it contains just the one pipeline, as in the last example). Just use while ... done < input.txt > output.txt.
      – chepner
      Nov 2 '18 at 15:58












    • @chepner Right it isn't necessary. But I prefer to have it by default as it's handy for printing a header/footer etc
      – nodakai
      Nov 3 '18 at 8:09
















    The command group isn't necessary, if the only command in it is the while loop (or if it contains just the one pipeline, as in the last example). Just use while ... done < input.txt > output.txt.
    – chepner
    Nov 2 '18 at 15:58






    The command group isn't necessary, if the only command in it is the while loop (or if it contains just the one pipeline, as in the last example). Just use while ... done < input.txt > output.txt.
    – chepner
    Nov 2 '18 at 15:58














    @chepner Right it isn't necessary. But I prefer to have it by default as it's handy for printing a header/footer etc
    – nodakai
    Nov 3 '18 at 8:09




    @chepner Right it isn't necessary. But I prefer to have it by default as it's handy for printing a header/footer etc
    – nodakai
    Nov 3 '18 at 8:09











    0














    Your script could be something like



    #!/bin/ksh
    input=$(seq -w 0 999)
    for i in $input
    do
    if [ $(($i%2)) -eq 0 ];then
    echo $i "even" >> output.txt
    else
    echo $i "odd" >> output.txt
    fi
    done


    then your output will be something like



    000 even
    001 odd
    002 even
    003 odd
    004 even
    005 odd
    006 even
    007 odd


    Then you could grep "even" or "odd" and execute what you need or you could execute your command directly inside the if/else statement.






    share|improve this answer























    • Do you know how I can do this for every single line all the way to 999, instead of stopping at 007? It seems to have a problem after line 9.
      – bear443
      Nov 1 '18 at 18:32












    • just edited, this works well
      – Valentino Di domenico
      Nov 2 '18 at 13:00
















    0














    Your script could be something like



    #!/bin/ksh
    input=$(seq -w 0 999)
    for i in $input
    do
    if [ $(($i%2)) -eq 0 ];then
    echo $i "even" >> output.txt
    else
    echo $i "odd" >> output.txt
    fi
    done


    then your output will be something like



    000 even
    001 odd
    002 even
    003 odd
    004 even
    005 odd
    006 even
    007 odd


    Then you could grep "even" or "odd" and execute what you need or you could execute your command directly inside the if/else statement.






    share|improve this answer























    • Do you know how I can do this for every single line all the way to 999, instead of stopping at 007? It seems to have a problem after line 9.
      – bear443
      Nov 1 '18 at 18:32












    • just edited, this works well
      – Valentino Di domenico
      Nov 2 '18 at 13:00














    0












    0








    0






    Your script could be something like



    #!/bin/ksh
    input=$(seq -w 0 999)
    for i in $input
    do
    if [ $(($i%2)) -eq 0 ];then
    echo $i "even" >> output.txt
    else
    echo $i "odd" >> output.txt
    fi
    done


    then your output will be something like



    000 even
    001 odd
    002 even
    003 odd
    004 even
    005 odd
    006 even
    007 odd


    Then you could grep "even" or "odd" and execute what you need or you could execute your command directly inside the if/else statement.






    share|improve this answer














    Your script could be something like



    #!/bin/ksh
    input=$(seq -w 0 999)
    for i in $input
    do
    if [ $(($i%2)) -eq 0 ];then
    echo $i "even" >> output.txt
    else
    echo $i "odd" >> output.txt
    fi
    done


    then your output will be something like



    000 even
    001 odd
    002 even
    003 odd
    004 even
    005 odd
    006 even
    007 odd


    Then you could grep "even" or "odd" and execute what you need or you could execute your command directly inside the if/else statement.







    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Nov 2 '18 at 12:59

























    answered Nov 1 '18 at 18:20









    Valentino Di domenicoValentino Di domenico

    464




    464












    • Do you know how I can do this for every single line all the way to 999, instead of stopping at 007? It seems to have a problem after line 9.
      – bear443
      Nov 1 '18 at 18:32












    • just edited, this works well
      – Valentino Di domenico
      Nov 2 '18 at 13:00


















    • Do you know how I can do this for every single line all the way to 999, instead of stopping at 007? It seems to have a problem after line 9.
      – bear443
      Nov 1 '18 at 18:32












    • just edited, this works well
      – Valentino Di domenico
      Nov 2 '18 at 13:00
















    Do you know how I can do this for every single line all the way to 999, instead of stopping at 007? It seems to have a problem after line 9.
    – bear443
    Nov 1 '18 at 18:32






    Do you know how I can do this for every single line all the way to 999, instead of stopping at 007? It seems to have a problem after line 9.
    – bear443
    Nov 1 '18 at 18:32














    just edited, this works well
    – Valentino Di domenico
    Nov 2 '18 at 13:00




    just edited, this works well
    – Valentino Di domenico
    Nov 2 '18 at 13:00











    0














    This works too:



    #!/bin/bash
    for x in `seq -w 0 999`; do
    if [ $((10#$x%2)) == 0 ]; then
    echo $x even
    else
    echo $x odd
    fi
    done > output.txt





    share|improve this answer


























      0














      This works too:



      #!/bin/bash
      for x in `seq -w 0 999`; do
      if [ $((10#$x%2)) == 0 ]; then
      echo $x even
      else
      echo $x odd
      fi
      done > output.txt





      share|improve this answer
























        0












        0








        0






        This works too:



        #!/bin/bash
        for x in `seq -w 0 999`; do
        if [ $((10#$x%2)) == 0 ]; then
        echo $x even
        else
        echo $x odd
        fi
        done > output.txt





        share|improve this answer












        This works too:



        #!/bin/bash
        for x in `seq -w 0 999`; do
        if [ $((10#$x%2)) == 0 ]; then
        echo $x even
        else
        echo $x odd
        fi
        done > output.txt






        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 13 '18 at 10:33









        gopygopy

        1637




        1637






























            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • 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%2fstackoverflow.com%2fquestions%2f53106466%2fbash-bug-fix-reading-a-text-file-line-by-line-and-acting-upon-the-lines%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

            List item for chat from Array inside array React Native

            Thiostrepton

            Caerphilly