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

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.

Related

Get specific output from grep [duplicate]

This question already has answers here:
How to get the second column from command output?
(8 answers)
Closed 3 years ago.
I am trying to get a specific output using grep but I am unable to do so.
Here is my grep command :
crictl inspect 47aaecb541688accf37840108cc0d19b39b84f8337740edf2ca7e5e81a24328e | grep "io.kubernetes.pod.namespace"
The output of the above command is "io.kubernetes.pod.namespace": "kube-system",
I even tried
crictl inspect 47aaecb541688accf37840108cc0d19b39b84f8337740edf2ca7e5e81a24328e | grep -Po '(?<="io.kubernetes.pod.namespace": ").*' but the output i got is kube-system",
I just want the value i.e just kube-system
How do I modify my grep command.
Thanks for the help
Using grep
We need to make just one small change to the grep -P command. Your command was:
$ echo '"io.kubernetes.pod.namespace": "kube-system",' | grep -Po '(?<="io.kubernetes.pod.namespace": ").*'
kube-system",
We just need to replace .* (which matches everything to the end of the line) with [^"]* with matches everything up to but not including the first ":
$ echo '"io.kubernetes.pod.namespace": "kube-system",' | grep -Po '(?<="io.kubernetes.pod.namespace": ")[^"]*'
kube-system
Or, using your crictl command:
crictl inspect 47aaecb541688accf37840108cc0d19b39b84f8337740edf2ca7e5e81a24328e | grep -Po '(?<="io.kubernetes.pod.namespace": ")[^"]*'
Using sed
$ echo '"io.kubernetes.pod.namespace": "kube-system",' | sed -n '/"io.kubernetes.pod.namespace"/{s/.*": "//; s/".*//p}'
kube-system
How it works:
-n tells sed not to print unless we explicitly ask it to.
/"io.kubernetes.pod.namespace"/{...} selects only those lines that contain "io.kubernetes.pod.namespace" and performs the commands in braces on them.
s/.*": "// removes everything from the beginning of the line to the last occurrence of ": ".
s/".*//p removes everything from the first remaining " to the end of the line and prints the result.

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".

num = 'ps -ef | grep -v grep| grep BatchName| wc -l' [duplicate]

This question already has an answer here:
UNIX grep command (grep -v grep)
(1 answer)
Closed 7 years ago.
I am having the basic knowledge of Unix. I'm programming for a wrapper script but in the above line of code I'm not getting the meaning and output of "grep -v grep". Please explain that in detail. Try to explain requested part only, it would be great help.
Thanks
It's excluding the grep process from the results, that's it. Run
grep --help
And you'll see
-v, --invert-match select non-matching lines
So the line
xxxx 27731 27613 0 17:21 pts/14 00:00:00 grep --color=auto /bin/bash
won't be returned as a result since we excluded "grep".

display all the ssh pids where the users are connected to in one line [duplicate]

This question already has answers here:
How to join multiple lines of filenames into one with custom delimiter
(22 answers)
Closed 7 years ago.
How can I display all the ssh pids where the users are connected to in one line separated by comma ?
This command displays the output in multiple lines, I would like to have the output in one line.
ps aux | grep -i "ssh" | awk '{print $2}'
from
1325
3255
2323
5321
3252
To
1325, 3255, 2323, 5321, 3252
Thank You!
You may want to use pgrep to get the processes IDs directly:
$ pgrep ssh
1217
5305
This way, you avoid calling ps aux and parsing its output, which will always contain the grep itself.
To join them on a ,-separated list, use paste on a -serial mode:
$ pgrep ssh | paste -s -d,
1217,5305
You could use sed utility in another pipe, so the command would be:
ps aux | grep -i "ssh" | awk '{print $2}' | sed ':a;{N;s/\n/, /};ba'
Where you are in fact replacing new lines (except the final one) by commas.

How to capture the output of a bash command into a variable when using pipes and apostrophe? [duplicate]

This question already has answers here:
How do I set a variable to the output of a command in Bash?
(15 answers)
Closed 6 years ago.
I am not sure how to save the output of a command via bash into a variable:
PID = 'ps -ef | grep -v color=auto | grep raspivid | awk '{print $2}''
Do I have to use a special character for the apostrophe or for the pipes?
Thanks!
To capture the output of a command in shell, use command substitution: $(...). Thus:
pid=$(ps -ef | grep -v color=auto | grep raspivid | awk '{print $2}')
Notes
When making an assignment in shell, there must be no spaces around the equal sign.
When defining shell variables for local use, it is best practice to use lower case or mixed case. Variables that are important to the system are defined in upper case and you don't want to accidentally overwrite one of them.
Simplification
If the goal is to get the PID of the raspivid process, then the grep and awk can be combined into a single process:
pid=$(ps -ef | awk '/[r]aspivid/{print $2}')
Note the simple trick that excludes the current process from the output: instead of searching for raspivid we search for [r]aspivid. The string [r]aspivid does not match the regular expression [r]aspivid. Hence the current process is removed from the output.
The Flexibility of awk
For the purpose of showing how awk can replace multiple calls to grep, consider this scenario: suppose that we want to find lines that contain raspivid but that do not contain color=auto. With awk, both conditions can be combined logically:
pid=$(ps -ef | awk '/raspivid/ && !/color=auto/{print $2}')
Here, /raspivid/ requires a match with raspivid. The && symbol means logical "and". The ! before the regex /color=auto/ means logical "not". Thus, /raspivid/ && !/color=auto/ matches only on lines that contain raspivid but not color=auto.
A more straightforward approach:
pid=$(pgrep raspivid)
... or a little different
echo pgrep [t]eleport

Resources