Bash Bug Fix: Reading a text file line by line and acting upon the lines
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
add a comment |
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
See Bash FAQ 001 for the correct way to iterate through a file line by line.
– chepner
Nov 2 '18 at 15:57
add a comment |
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
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
bash shell scripting sh
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
add a comment |
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
add a comment |
4 Answers
4
active
oldest
votes
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
- Keep in mind that arithmetic expansion
(( .. ))can do comparisions. It's clear toif (( 10#$i % 2 == 0 )); then. - I find
printf "%03d" "$i"to be just clearer in this case. - 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).
input=$(cat ...); for i in $inputis just bad. Don't read lines with for
- I don't like temp files.
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
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
|
show 1 more comment
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
The command group isn't necessary, if the only command in it is thewhileloop (or if it contains just the one pipeline, as in the last example). Just usewhile ... 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
add a comment |
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.
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
add a comment |
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
add a comment |
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
});
}
});
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%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
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
- Keep in mind that arithmetic expansion
(( .. ))can do comparisions. It's clear toif (( 10#$i % 2 == 0 )); then. - I find
printf "%03d" "$i"to be just clearer in this case. - 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).
input=$(cat ...); for i in $inputis just bad. Don't read lines with for
- I don't like temp files.
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
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
|
show 1 more comment
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
- Keep in mind that arithmetic expansion
(( .. ))can do comparisions. It's clear toif (( 10#$i % 2 == 0 )); then. - I find
printf "%03d" "$i"to be just clearer in this case. - 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).
input=$(cat ...); for i in $inputis just bad. Don't read lines with for
- I don't like temp files.
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
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
|
show 1 more comment
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
- Keep in mind that arithmetic expansion
(( .. ))can do comparisions. It's clear toif (( 10#$i % 2 == 0 )); then. - I find
printf "%03d" "$i"to be just clearer in this case. - 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).
input=$(cat ...); for i in $inputis just bad. Don't read lines with for
- I don't like temp files.
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
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
- Keep in mind that arithmetic expansion
(( .. ))can do comparisions. It's clear toif (( 10#$i % 2 == 0 )); then. - I find
printf "%03d" "$i"to be just clearer in this case. - 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).
input=$(cat ...); for i in $inputis just bad. Don't read lines with for
- I don't like temp files.
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
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
|
show 1 more comment
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
|
show 1 more comment
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
The command group isn't necessary, if the only command in it is thewhileloop (or if it contains just the one pipeline, as in the last example). Just usewhile ... 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
add a comment |
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
The command group isn't necessary, if the only command in it is thewhileloop (or if it contains just the one pipeline, as in the last example). Just usewhile ... 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
add a comment |
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
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
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 thewhileloop (or if it contains just the one pipeline, as in the last example). Just usewhile ... 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
add a comment |
The command group isn't necessary, if the only command in it is thewhileloop (or if it contains just the one pipeline, as in the last example). Just usewhile ... 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
add a comment |
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.
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
add a comment |
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.
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
add a comment |
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.
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.
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
add a comment |
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
add a comment |
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
add a comment |
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
add a comment |
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
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
answered Nov 13 '18 at 10:33
gopygopy
1637
1637
add a comment |
add a comment |
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.
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%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
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
See Bash FAQ 001 for the correct way to iterate through a file line by line.
– chepner
Nov 2 '18 at 15:57