Is it possible to use tail and grep in combination? [duplicate] - linux

This question already has answers here:
How to 'grep' a continuous stream?
(13 answers)
Closed 8 years ago.
I am trying to tail a user in production log.
Is it possible to use
tail -f grep "username"

Yes - You use pipe. i.e.
tail -f <some filename> | grep 'username'

Yes, you can just use a pipe
tail -f fileName | grep username

The ack command, which is a grep-like text finder, has a --passthru flag that is designed specifically for this.
Since ack automatically color codes matches for you, you can use it to search the output of a tailed log file, and highlight the matches, but also see the lines that don't match.
tail -f error.log | ack --passthru whatever
All the lines of the tailed log will show up, but the matches will be highlighted.
ack is at http://beyondgrep.com/

factually I have found it to be more efficient to use:
grep username filename | tail

Related

Use grep and get text after the pattern [duplicate]

This question already has answers here:
How to grep for contents after pattern?
(8 answers)
Closed 4 years ago.
I need to get the IP from a log I need to grep the true-client and after that I need to grep true-client-ip=[191.168.171.15] and get just the IP
2019.02.14-08:26:06:713,asd:1234:chan,0.000,asd,S,request-begin-site,POST,{remoteHost=1.2.3.4,remoteAddr=1.2.3.4,requestType=POST,serverName=api=[text/html],accept-charset=[iso-12345-15, utf-8;q=0.5, *;q=0.5],accept-encoding=[gzip],server-origin=[5],cache-control=[no-cache, max-age=0],pragma=[no-cache],program-header=[true],te=[chunked;q=1.0],true-client-ip=[191.168.171.15],true-host=[www.server.com]
I was trying grep -o "true-client-ip=[^ ]*," but it brings me:
true-client-ip=[191.168.171.15],true-host=[www.server.com]
I need just true-client-ip=[191.168.171.15] so I can cut after to bring get the IP like true-client-ip=[191.168.171.15] | cut -d= -f2
Using grep -P flag if available :
grep -oP 'true-client-ip=\[\K[^]]*'
Perl's \K meta-character discards what precedes when displaying the result, so it will match the "true-client-ip=[" part but only display the IP.
If grep -P isn't available, I would use sed :
sed -nE 's/.*true-client-ip=\[([^]]*).*/\1/p'
If you have GNU grep, you can do it like this:
$ grep -oP "(?<=true-client-ip=\[)[^\]]*" file
191.168.171.15
The (?<=) is called Positive Lookbehind, which you can find related doc here.
The backslash \ in [^\]] is actually unnecessary, I just feel like to add it to make it more intuitive, less misleading-prone :-) .

grepping output of ps, exclude the word grep [duplicate]

This question already has answers here:
More elegant "ps aux | grep -v grep"
(9 answers)
Closed 3 years ago.
I'm using ps to find the pid of a process created to execute the command "sleep 1234 &"
I grep the result to match only "sleep 1234".
ps -A -f | grep "sleep 1234"
however, this matches also the command "grep sleep 1234" itself, returning two lines instead of one. How do I write a pattern for grep to exclude the word 'grep' itself?
Thanks
This is a pretty common problem and the easiest solution is to just surround a character in the grep'ed pattern with square brackets:
ps -A -f | grep "[s]leep 1234"
This will now match sleep 1234, but not [s]leep 1234 (because of the literal ] between s and l), and the grep line no longer matches.
The reason that the grep is in the process list is that pipelines are executed from right to left, so the grep is actually executed prior to the ps.

I'm trying to understand how to use special characters in grep and wc [duplicate]

This question already has an answer here:
Reference - What does this regex mean?
(1 answer)
Closed 6 years ago.
Can you explain in detail what happened here on this command?
grep -nw '^root' /etc/passwd
What is the use of ^ and '? Please give me examples and be detailed cuz all I'm hearing is that it's the beginning of the line. I don't understand what each of those special characters means.
How would I go about using wc, grep and ^ to find out the number of non-root processes running on my system?
grep -nw '^root' /etc/passwd
It reads the /etc/passwd file line-by-line and filters out all those lines that ^=begin with the -w=complete word "root". So, for example the line
root:x:0:0:root:/root:/bin/bash
To see all processes on a system, you could use ps aux. and it will show lines like this
root 22866 0.0 [...] 0:00 [kworker/1:0]
As you can see, the lines start with a username. If you pipe the ps aux output through grep, you can use the same RegEx from above, to filter out all lines that do not start with "root".
Use -v to invert pattern matching, so that grep -vw '^root' finds all lines that don't begin with a complete word "root".
ps aux | grep -vw '^root' | wc -l
Finally, wc -l counts the number of lines it receives. So that is the number of all lines from ps aux that do not begin with "root".

Preserve colouring after piping grep to grep

There is a simlar question in Preserve ls colouring after grep’ing but it annoys me that if you pipe colored grep output into another grep that the coloring is not preserved.
As an example grep --color WORD * | grep -v AVOID does not keep the color of the first output. But for me ls | grep FILE do keep the color, why the difference ?
grep sometimes disables the color output, for example when writing to a pipe. You can override this behavior with grep --color=always
The correct command line would be
grep --color=always WORD * | grep -v AVOID
This is pretty verbose, alternatively you can just add the line
alias cgrep="grep --color=always"
to your .bashrc for example and use cgrep as the colored grep. When redefining grep you might run into trouble with scripts which rely on specific output of grep and don't like ascii escape code.
A word of advice:
When using grep --color=always, the actual strings being passed on to the next pipe will be changed. This can lead to the following situation:
$ grep --color=always -e '1' * | grep -ve '12'
11
12
13
Even though the option -ve '12' should exclude the middle line, it will not because there are color characters between 1 and 2.
The existing answers only address the case when the FIRST command is grep (as asked by the OP, but this problem arises in other situations too).
More general answer
The basic problem is that the command BEFORE | grep, tries to be "smart" by disabling color when it realizes the output is going to a pipe. This is usually what you want so that ANSI escape codes don't interfere with your downstream program.
But if you want colorized output emanating from earlier commands, you need to force color codes to be produced regardless of the output sink. The forcing mechanism is program-specific.
Git: use -c color.status=always
git -c color.status=always status | grep -v .DS_Store
Note: the -c option must come BEFORE the subcommand status.
Others
(this is a community wiki post so feel free to add yours)
Simply repeat the same grep command at the end of your pipe.
grep WORD * | grep -v AVOID | grep -v AVOID2 | grep WORD

How can I print intermediate results from a pipeline to the screen? [duplicate]

This question already has answers here:
How can I gzip standard in to a file and also print standard in to standard out?
(4 answers)
Closed 7 years ago.
I'm trying to count the lines from a command and I'd also like to see the lines as they go by. My initial thought was to use the tee command:
complicated_command | tee - | wc -l
But that simply doubles the line count using GNU tee or copies output to a file named - on Solaris.
complicated_command | tee /dev/tty | wc -l
But keep in mind that if you put it in a script and redirect the output, it won't do what you expect.
The solution is to tee to the console directly as opposed to STDOUT:
tty=`tty`
complicated_command | tee $tty | wc -l

Resources