Redirection and piping for grepping
Clash Royale CLAN TAG#URR8PPP
up vote
1
down vote
favorite
I'm working on a script that will run a checksum process which outputs to STDOUT, which I then want to grep for lines matching OK, or FAILED and do different things with those matches (i.e. output to terminal and log). I've watched a ton of Youtube videos and read a ton about redirection, but I just can't seem to wrap my head around how exactly redirection works. What I'm trying to do is chain STDOUT to multiple greps without them gobbling up the non-matched text.
Here's a concept of what I'm trying using cat instead of md5sum with a text file of animal names on each line (DOG, CAT, PONY, RHINO, DEER, FOX):
cat test.txt 3>&1 3> results.txt
This does what I expect. What I understand here is I'm doing a cat on the file, and then opening fd3 which points to whatever is written to STDOUT(fd1). Since the grep will gobble up everything from fd1, I tee the STDOUT of cat explicitly to fd3 and then pipe the STDOUT to grep. Grep will print out the line matching DOG, and then all the text written to fd3 from cat will get pushed to a results.txt file.
Now, to chain another grep to look for other text I have to point the fd3 data back into STDOUT, tee it explicitly back to fd3 and then pipe STDOUT to a new grep.
tee /dev/fd/3 3> results.txt
The first problem here is the STDOUT from the first grep is being pushed into fd3 a second time instead of printing to the terminal. So now my results.txt is getting duplicates and I never got anything printed to the screen for the first grep. This is where my understanding of redirections is falling apart. I sort-of get what's happening but I can't figure out a simple solution.
I want to grep STDOUT, print the results to screen, and pass the original text to another grep, and maybe a third, fourth, etc without modifying the original text I'm passing to each GREP, and without each subsequent grep eating up the previous' match that should print to screen.
I could probably do this by storing a variable and calling it on multiple lines of greps, but then I have to wait for the entire first command to complete. In the case of the application I'm working on, I want to see realtime results during a checksum, not just a blank screen for an hour until the whole process is complete. Any clarification on what I'm doing wrong would be super helpful, thanks!
EDIT
I understand this exact use of cat is pointless, I just used it to demonstrate the concept. In the script I'll be applying the concept to, the first command is actually:
md5sum -c checksum.md5
Which will read a checksum file, re-hash the the source and output to STDOUT a pass/fail line. I then want to grep this stream and send the results to separate logs and/or terminal output - but cat seemed like a simpler way to demonstrate the problem as this can be applied to filtering any command and grepping the stream, such as find, md5, ls, etc.
bash grep io-redirection tee
add a comment |Â
up vote
1
down vote
favorite
I'm working on a script that will run a checksum process which outputs to STDOUT, which I then want to grep for lines matching OK, or FAILED and do different things with those matches (i.e. output to terminal and log). I've watched a ton of Youtube videos and read a ton about redirection, but I just can't seem to wrap my head around how exactly redirection works. What I'm trying to do is chain STDOUT to multiple greps without them gobbling up the non-matched text.
Here's a concept of what I'm trying using cat instead of md5sum with a text file of animal names on each line (DOG, CAT, PONY, RHINO, DEER, FOX):
cat test.txt 3>&1 3> results.txt
This does what I expect. What I understand here is I'm doing a cat on the file, and then opening fd3 which points to whatever is written to STDOUT(fd1). Since the grep will gobble up everything from fd1, I tee the STDOUT of cat explicitly to fd3 and then pipe the STDOUT to grep. Grep will print out the line matching DOG, and then all the text written to fd3 from cat will get pushed to a results.txt file.
Now, to chain another grep to look for other text I have to point the fd3 data back into STDOUT, tee it explicitly back to fd3 and then pipe STDOUT to a new grep.
tee /dev/fd/3 3> results.txt
The first problem here is the STDOUT from the first grep is being pushed into fd3 a second time instead of printing to the terminal. So now my results.txt is getting duplicates and I never got anything printed to the screen for the first grep. This is where my understanding of redirections is falling apart. I sort-of get what's happening but I can't figure out a simple solution.
I want to grep STDOUT, print the results to screen, and pass the original text to another grep, and maybe a third, fourth, etc without modifying the original text I'm passing to each GREP, and without each subsequent grep eating up the previous' match that should print to screen.
I could probably do this by storing a variable and calling it on multiple lines of greps, but then I have to wait for the entire first command to complete. In the case of the application I'm working on, I want to see realtime results during a checksum, not just a blank screen for an hour until the whole process is complete. Any clarification on what I'm doing wrong would be super helpful, thanks!
EDIT
I understand this exact use of cat is pointless, I just used it to demonstrate the concept. In the script I'll be applying the concept to, the first command is actually:
md5sum -c checksum.md5
Which will read a checksum file, re-hash the the source and output to STDOUT a pass/fail line. I then want to grep this stream and send the results to separate logs and/or terminal output - but cat seemed like a simpler way to demonstrate the problem as this can be applied to filtering any command and grepping the stream, such as find, md5, ls, etc.
bash grep io-redirection tee
The redirection incat test.txt 3>&1
doesn't make any sense as it is never used. The whole cat is useless:<test.txt tee ...
â Hauke Laging
Jan 13 at 23:38
What do you needresults.txt
for? It is just a copy oftest.txt
â Hauke Laging
Jan 13 at 23:45
@HaukeLaging I edited my post to to clarify that the first command doesn't really matter, and I'd really be using this where the first command is generating a new stream of text, rather than a simple read of a file which I used to just demonstrate the concept.
â iceblueorbitz
Jan 14 at 0:02
add a comment |Â
up vote
1
down vote
favorite
up vote
1
down vote
favorite
I'm working on a script that will run a checksum process which outputs to STDOUT, which I then want to grep for lines matching OK, or FAILED and do different things with those matches (i.e. output to terminal and log). I've watched a ton of Youtube videos and read a ton about redirection, but I just can't seem to wrap my head around how exactly redirection works. What I'm trying to do is chain STDOUT to multiple greps without them gobbling up the non-matched text.
Here's a concept of what I'm trying using cat instead of md5sum with a text file of animal names on each line (DOG, CAT, PONY, RHINO, DEER, FOX):
cat test.txt 3>&1 3> results.txt
This does what I expect. What I understand here is I'm doing a cat on the file, and then opening fd3 which points to whatever is written to STDOUT(fd1). Since the grep will gobble up everything from fd1, I tee the STDOUT of cat explicitly to fd3 and then pipe the STDOUT to grep. Grep will print out the line matching DOG, and then all the text written to fd3 from cat will get pushed to a results.txt file.
Now, to chain another grep to look for other text I have to point the fd3 data back into STDOUT, tee it explicitly back to fd3 and then pipe STDOUT to a new grep.
tee /dev/fd/3 3> results.txt
The first problem here is the STDOUT from the first grep is being pushed into fd3 a second time instead of printing to the terminal. So now my results.txt is getting duplicates and I never got anything printed to the screen for the first grep. This is where my understanding of redirections is falling apart. I sort-of get what's happening but I can't figure out a simple solution.
I want to grep STDOUT, print the results to screen, and pass the original text to another grep, and maybe a third, fourth, etc without modifying the original text I'm passing to each GREP, and without each subsequent grep eating up the previous' match that should print to screen.
I could probably do this by storing a variable and calling it on multiple lines of greps, but then I have to wait for the entire first command to complete. In the case of the application I'm working on, I want to see realtime results during a checksum, not just a blank screen for an hour until the whole process is complete. Any clarification on what I'm doing wrong would be super helpful, thanks!
EDIT
I understand this exact use of cat is pointless, I just used it to demonstrate the concept. In the script I'll be applying the concept to, the first command is actually:
md5sum -c checksum.md5
Which will read a checksum file, re-hash the the source and output to STDOUT a pass/fail line. I then want to grep this stream and send the results to separate logs and/or terminal output - but cat seemed like a simpler way to demonstrate the problem as this can be applied to filtering any command and grepping the stream, such as find, md5, ls, etc.
bash grep io-redirection tee
I'm working on a script that will run a checksum process which outputs to STDOUT, which I then want to grep for lines matching OK, or FAILED and do different things with those matches (i.e. output to terminal and log). I've watched a ton of Youtube videos and read a ton about redirection, but I just can't seem to wrap my head around how exactly redirection works. What I'm trying to do is chain STDOUT to multiple greps without them gobbling up the non-matched text.
Here's a concept of what I'm trying using cat instead of md5sum with a text file of animal names on each line (DOG, CAT, PONY, RHINO, DEER, FOX):
cat test.txt 3>&1 3> results.txt
This does what I expect. What I understand here is I'm doing a cat on the file, and then opening fd3 which points to whatever is written to STDOUT(fd1). Since the grep will gobble up everything from fd1, I tee the STDOUT of cat explicitly to fd3 and then pipe the STDOUT to grep. Grep will print out the line matching DOG, and then all the text written to fd3 from cat will get pushed to a results.txt file.
Now, to chain another grep to look for other text I have to point the fd3 data back into STDOUT, tee it explicitly back to fd3 and then pipe STDOUT to a new grep.
tee /dev/fd/3 3> results.txt
The first problem here is the STDOUT from the first grep is being pushed into fd3 a second time instead of printing to the terminal. So now my results.txt is getting duplicates and I never got anything printed to the screen for the first grep. This is where my understanding of redirections is falling apart. I sort-of get what's happening but I can't figure out a simple solution.
I want to grep STDOUT, print the results to screen, and pass the original text to another grep, and maybe a third, fourth, etc without modifying the original text I'm passing to each GREP, and without each subsequent grep eating up the previous' match that should print to screen.
I could probably do this by storing a variable and calling it on multiple lines of greps, but then I have to wait for the entire first command to complete. In the case of the application I'm working on, I want to see realtime results during a checksum, not just a blank screen for an hour until the whole process is complete. Any clarification on what I'm doing wrong would be super helpful, thanks!
EDIT
I understand this exact use of cat is pointless, I just used it to demonstrate the concept. In the script I'll be applying the concept to, the first command is actually:
md5sum -c checksum.md5
Which will read a checksum file, re-hash the the source and output to STDOUT a pass/fail line. I then want to grep this stream and send the results to separate logs and/or terminal output - but cat seemed like a simpler way to demonstrate the problem as this can be applied to filtering any command and grepping the stream, such as find, md5, ls, etc.
bash grep io-redirection tee
edited Jan 13 at 23:58
asked Jan 13 at 21:48
iceblueorbitz
84
84
The redirection incat test.txt 3>&1
doesn't make any sense as it is never used. The whole cat is useless:<test.txt tee ...
â Hauke Laging
Jan 13 at 23:38
What do you needresults.txt
for? It is just a copy oftest.txt
â Hauke Laging
Jan 13 at 23:45
@HaukeLaging I edited my post to to clarify that the first command doesn't really matter, and I'd really be using this where the first command is generating a new stream of text, rather than a simple read of a file which I used to just demonstrate the concept.
â iceblueorbitz
Jan 14 at 0:02
add a comment |Â
The redirection incat test.txt 3>&1
doesn't make any sense as it is never used. The whole cat is useless:<test.txt tee ...
â Hauke Laging
Jan 13 at 23:38
What do you needresults.txt
for? It is just a copy oftest.txt
â Hauke Laging
Jan 13 at 23:45
@HaukeLaging I edited my post to to clarify that the first command doesn't really matter, and I'd really be using this where the first command is generating a new stream of text, rather than a simple read of a file which I used to just demonstrate the concept.
â iceblueorbitz
Jan 14 at 0:02
The redirection in
cat test.txt 3>&1
doesn't make any sense as it is never used. The whole cat is useless: <test.txt tee ...
â Hauke Laging
Jan 13 at 23:38
The redirection in
cat test.txt 3>&1
doesn't make any sense as it is never used. The whole cat is useless: <test.txt tee ...
â Hauke Laging
Jan 13 at 23:38
What do you need
results.txt
for? It is just a copy of test.txt
â Hauke Laging
Jan 13 at 23:45
What do you need
results.txt
for? It is just a copy of test.txt
â Hauke Laging
Jan 13 at 23:45
@HaukeLaging I edited my post to to clarify that the first command doesn't really matter, and I'd really be using this where the first command is generating a new stream of text, rather than a simple read of a file which I used to just demonstrate the concept.
â iceblueorbitz
Jan 14 at 0:02
@HaukeLaging I edited my post to to clarify that the first command doesn't really matter, and I'd really be using this where the first command is generating a new stream of text, rather than a simple read of a file which I used to just demonstrate the concept.
â iceblueorbitz
Jan 14 at 0:02
add a comment |Â
2 Answers
2
active
oldest
votes
up vote
4
down vote
accepted
You can better do what you ask for with process substitution:
Being as close as your original command as possible:
cat test.txt | tee >(grep DOG) >(grep PONY) >results.txt
Removing the useless use of cat:
<test.txt tee >(grep DOG) >(grep PONY) >results.txt
Or:
tee >(grep DOG) >(grep PONY) <test.txt >results.txt
Useless use of cat
â Hauke Laging
Jan 13 at 23:36
While a useless use case for cat, the answer seems to point out a potential solution to the concept of filtering STDOUT into separate grep processes, which is all my original question was asking, first command being a moot point, as long as it prints something to STDOUT.
â iceblueorbitz
Jan 14 at 0:00
@HaukeLaging Thanks for the nitpicking. Solved. Please Remove your downvote.
â Isaac
Jan 14 at 1:50
This should not be downvoted, it provided a perfect solution to my question about redirecting stdout to multiple processes, regardless what command was used to create the initial stdout. Thanks @isaac
â iceblueorbitz
Jan 14 at 2:37
There is a downvote but it's not mine. I would not downvote an answer because of UUOC. I even made an upvote after the UUOC edit.
â Hauke Laging
Jan 14 at 10:32
add a comment |Â
up vote
1
down vote
isaac's solution is better but your way would look like this:
<input tee results.txt /dev/fd/3 3>&1 |
grep PONY >&2; 3>/dev/null
or for three
<input tee results.txt /dev/fd/3 3>&1 |
grep PONY >&2; 3>&1 |
tee /dev/fd/3 3>/dev/null
@isaac This can be extended as much as you like.
â Hauke Laging
Jan 14 at 10:26
@isaac See the edit
â Hauke Laging
Jan 14 at 11:09
add a comment |Â
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
4
down vote
accepted
You can better do what you ask for with process substitution:
Being as close as your original command as possible:
cat test.txt | tee >(grep DOG) >(grep PONY) >results.txt
Removing the useless use of cat:
<test.txt tee >(grep DOG) >(grep PONY) >results.txt
Or:
tee >(grep DOG) >(grep PONY) <test.txt >results.txt
Useless use of cat
â Hauke Laging
Jan 13 at 23:36
While a useless use case for cat, the answer seems to point out a potential solution to the concept of filtering STDOUT into separate grep processes, which is all my original question was asking, first command being a moot point, as long as it prints something to STDOUT.
â iceblueorbitz
Jan 14 at 0:00
@HaukeLaging Thanks for the nitpicking. Solved. Please Remove your downvote.
â Isaac
Jan 14 at 1:50
This should not be downvoted, it provided a perfect solution to my question about redirecting stdout to multiple processes, regardless what command was used to create the initial stdout. Thanks @isaac
â iceblueorbitz
Jan 14 at 2:37
There is a downvote but it's not mine. I would not downvote an answer because of UUOC. I even made an upvote after the UUOC edit.
â Hauke Laging
Jan 14 at 10:32
add a comment |Â
up vote
4
down vote
accepted
You can better do what you ask for with process substitution:
Being as close as your original command as possible:
cat test.txt | tee >(grep DOG) >(grep PONY) >results.txt
Removing the useless use of cat:
<test.txt tee >(grep DOG) >(grep PONY) >results.txt
Or:
tee >(grep DOG) >(grep PONY) <test.txt >results.txt
Useless use of cat
â Hauke Laging
Jan 13 at 23:36
While a useless use case for cat, the answer seems to point out a potential solution to the concept of filtering STDOUT into separate grep processes, which is all my original question was asking, first command being a moot point, as long as it prints something to STDOUT.
â iceblueorbitz
Jan 14 at 0:00
@HaukeLaging Thanks for the nitpicking. Solved. Please Remove your downvote.
â Isaac
Jan 14 at 1:50
This should not be downvoted, it provided a perfect solution to my question about redirecting stdout to multiple processes, regardless what command was used to create the initial stdout. Thanks @isaac
â iceblueorbitz
Jan 14 at 2:37
There is a downvote but it's not mine. I would not downvote an answer because of UUOC. I even made an upvote after the UUOC edit.
â Hauke Laging
Jan 14 at 10:32
add a comment |Â
up vote
4
down vote
accepted
up vote
4
down vote
accepted
You can better do what you ask for with process substitution:
Being as close as your original command as possible:
cat test.txt | tee >(grep DOG) >(grep PONY) >results.txt
Removing the useless use of cat:
<test.txt tee >(grep DOG) >(grep PONY) >results.txt
Or:
tee >(grep DOG) >(grep PONY) <test.txt >results.txt
You can better do what you ask for with process substitution:
Being as close as your original command as possible:
cat test.txt | tee >(grep DOG) >(grep PONY) >results.txt
Removing the useless use of cat:
<test.txt tee >(grep DOG) >(grep PONY) >results.txt
Or:
tee >(grep DOG) >(grep PONY) <test.txt >results.txt
edited Jan 14 at 1:48
answered Jan 13 at 21:59
Isaac
6,7711834
6,7711834
Useless use of cat
â Hauke Laging
Jan 13 at 23:36
While a useless use case for cat, the answer seems to point out a potential solution to the concept of filtering STDOUT into separate grep processes, which is all my original question was asking, first command being a moot point, as long as it prints something to STDOUT.
â iceblueorbitz
Jan 14 at 0:00
@HaukeLaging Thanks for the nitpicking. Solved. Please Remove your downvote.
â Isaac
Jan 14 at 1:50
This should not be downvoted, it provided a perfect solution to my question about redirecting stdout to multiple processes, regardless what command was used to create the initial stdout. Thanks @isaac
â iceblueorbitz
Jan 14 at 2:37
There is a downvote but it's not mine. I would not downvote an answer because of UUOC. I even made an upvote after the UUOC edit.
â Hauke Laging
Jan 14 at 10:32
add a comment |Â
Useless use of cat
â Hauke Laging
Jan 13 at 23:36
While a useless use case for cat, the answer seems to point out a potential solution to the concept of filtering STDOUT into separate grep processes, which is all my original question was asking, first command being a moot point, as long as it prints something to STDOUT.
â iceblueorbitz
Jan 14 at 0:00
@HaukeLaging Thanks for the nitpicking. Solved. Please Remove your downvote.
â Isaac
Jan 14 at 1:50
This should not be downvoted, it provided a perfect solution to my question about redirecting stdout to multiple processes, regardless what command was used to create the initial stdout. Thanks @isaac
â iceblueorbitz
Jan 14 at 2:37
There is a downvote but it's not mine. I would not downvote an answer because of UUOC. I even made an upvote after the UUOC edit.
â Hauke Laging
Jan 14 at 10:32
Useless use of cat
â Hauke Laging
Jan 13 at 23:36
Useless use of cat
â Hauke Laging
Jan 13 at 23:36
While a useless use case for cat, the answer seems to point out a potential solution to the concept of filtering STDOUT into separate grep processes, which is all my original question was asking, first command being a moot point, as long as it prints something to STDOUT.
â iceblueorbitz
Jan 14 at 0:00
While a useless use case for cat, the answer seems to point out a potential solution to the concept of filtering STDOUT into separate grep processes, which is all my original question was asking, first command being a moot point, as long as it prints something to STDOUT.
â iceblueorbitz
Jan 14 at 0:00
@HaukeLaging Thanks for the nitpicking. Solved. Please Remove your downvote.
â Isaac
Jan 14 at 1:50
@HaukeLaging Thanks for the nitpicking. Solved. Please Remove your downvote.
â Isaac
Jan 14 at 1:50
This should not be downvoted, it provided a perfect solution to my question about redirecting stdout to multiple processes, regardless what command was used to create the initial stdout. Thanks @isaac
â iceblueorbitz
Jan 14 at 2:37
This should not be downvoted, it provided a perfect solution to my question about redirecting stdout to multiple processes, regardless what command was used to create the initial stdout. Thanks @isaac
â iceblueorbitz
Jan 14 at 2:37
There is a downvote but it's not mine. I would not downvote an answer because of UUOC. I even made an upvote after the UUOC edit.
â Hauke Laging
Jan 14 at 10:32
There is a downvote but it's not mine. I would not downvote an answer because of UUOC. I even made an upvote after the UUOC edit.
â Hauke Laging
Jan 14 at 10:32
add a comment |Â
up vote
1
down vote
isaac's solution is better but your way would look like this:
<input tee results.txt /dev/fd/3 3>&1 |
grep PONY >&2; 3>/dev/null
or for three
<input tee results.txt /dev/fd/3 3>&1 |
grep PONY >&2; 3>&1 |
tee /dev/fd/3 3>/dev/null
@isaac This can be extended as much as you like.
â Hauke Laging
Jan 14 at 10:26
@isaac See the edit
â Hauke Laging
Jan 14 at 11:09
add a comment |Â
up vote
1
down vote
isaac's solution is better but your way would look like this:
<input tee results.txt /dev/fd/3 3>&1 |
grep PONY >&2; 3>/dev/null
or for three
<input tee results.txt /dev/fd/3 3>&1 |
grep PONY >&2; 3>&1 |
tee /dev/fd/3 3>/dev/null
@isaac This can be extended as much as you like.
â Hauke Laging
Jan 14 at 10:26
@isaac See the edit
â Hauke Laging
Jan 14 at 11:09
add a comment |Â
up vote
1
down vote
up vote
1
down vote
isaac's solution is better but your way would look like this:
<input tee results.txt /dev/fd/3 3>&1 |
grep PONY >&2; 3>/dev/null
or for three
<input tee results.txt /dev/fd/3 3>&1 |
grep PONY >&2; 3>&1 |
tee /dev/fd/3 3>/dev/null
isaac's solution is better but your way would look like this:
<input tee results.txt /dev/fd/3 3>&1 |
grep PONY >&2; 3>/dev/null
or for three
<input tee results.txt /dev/fd/3 3>&1 |
grep PONY >&2; 3>&1 |
tee /dev/fd/3 3>/dev/null
edited Jan 14 at 11:08
answered Jan 13 at 23:58
Hauke Laging
53.4k1282130
53.4k1282130
@isaac This can be extended as much as you like.
â Hauke Laging
Jan 14 at 10:26
@isaac See the edit
â Hauke Laging
Jan 14 at 11:09
add a comment |Â
@isaac This can be extended as much as you like.
â Hauke Laging
Jan 14 at 10:26
@isaac See the edit
â Hauke Laging
Jan 14 at 11:09
@isaac This can be extended as much as you like.
â Hauke Laging
Jan 14 at 10:26
@isaac This can be extended as much as you like.
â Hauke Laging
Jan 14 at 10:26
@isaac See the edit
â Hauke Laging
Jan 14 at 11:09
@isaac See the edit
â Hauke Laging
Jan 14 at 11:09
add a comment |Â
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
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f416918%2fredirection-and-piping-for-grepping%23new-answer', 'question_page');
);
Post as a guest
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
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
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
The redirection in
cat test.txt 3>&1
doesn't make any sense as it is never used. The whole cat is useless:<test.txt tee ...
â Hauke Laging
Jan 13 at 23:38
What do you need
results.txt
for? It is just a copy oftest.txt
â Hauke Laging
Jan 13 at 23:45
@HaukeLaging I edited my post to to clarify that the first command doesn't really matter, and I'd really be using this where the first command is generating a new stream of text, rather than a simple read of a file which I used to just demonstrate the concept.
â iceblueorbitz
Jan 14 at 0:02