SH grep output only certain string - grep

Im trying to get a certain part of my output from grep. Currently I get the full text that could look like: "Location: /path/to/file" or "State: Error". However I want to only print the second part that is "/path/to/file" and "Error". Observe that one output contains "Elapsed time: 568 hours (23.6 days)" and I need to remove the hours (23.6 days) part. These are all different grep and unique code can be used for each one.
So what I expect as a result is to give the input:
Elapsed time: 568 hours (23.6 days)
and the output should be 568
For the other example I expect as a result is to give the input:
State: Error
And the output should be Error
I tried to check up something called awk and sed, got a little confused and not very clear how to implement it on my problem.
`grep "Elapsed Time: *" | sed -e 's/Elapsed Time://g'`
this would print out 568 hours (23.6 days).
grep "Location: *" | sed -e 's/Location://g'
works but contains a lot of empty space between Location: and /path/to/file, can the spaces be removed in one go aswell?

If row contains Elapsed time: print third column:
echo 'Elapsed time: 568 hours (23.6 days)' | awk '/Elapsed time:/{print $3}'
or with GNU grep and Perl-compatible regular expression (PCRE)
echo 'Elapsed time: 568 hours (23.6 days)' | grep -Po 'Elapsed time: *\K.*(?= hours)'
or with GNU sed and extended regex:
echo 'Elapsed time: 568 hours (23.6 days)' | sed -r 's/Elapsed time: *(.*) hours.*/\1/'
Output:
568

Related

Extract specific number from command outout

I have the following issue.
In a script, I have to execute the hdparm command on /dev/xvda1 path.
From the command output, I have to extract the MB/sec values calculated.
So, for example, if executing the command I have this output:
/dev/xvda1:
Timing cached reads: 15900 MB in 1.99 seconds = 7986.93 MB/sec
Timing buffered disk reads: 478 MB in 3.00 seconds = 159.09 MB/sec
I have to extract 7986.93 and 159.09.
I tried:
grep -o -E '[0-9]+', but it returns to me all the six number in the output
grep -o -E '[0-9]', but it return to me only the first character of the six values.
grep -o -E '[0-9]+$', but the output is empty, I suppose because the number is not the last character set of outoput.
How can I achieve my purpose?
To get the last number, you can add a .* in front, that will match as much as possible, eating away all the other numbers. However, to exclude that part from the output, you need GNU grep or pcregrep or sed.
grep -Po '.* \K[0-9.]+'
Or
sed -En 's/.* ([0-9.]+).*/\1/p'
Consider using awk to just print the fields you want rather than matching on numbers. This will work using any awk in any shell on every Unix box:
$ hdparm whatever | awk 'NF>1{print $(NF-1)}'
7986.93
159.09

Conky cpubar filling in wrong way

I have a simple conky cpubar for monitoring CPU load working on Debian KDE 9, here is the relevant part:
${image ~/script/conky/static/img/cpu.png -p 0,280 -s 26x26}\
${goto 40}${font monospace:bold:size=15}${color1}CPU ${font monospace:bold:size=10}(TOT: ${cpu cpu0}%) ${color0}${hr 5}${color white}
${font monospace:bold:size=11}\
${execi 99999 neofetch | grep 'CPU' | cut -f 2 -d ":" | sed 's/^[ \t]*//;s/[ \t]*$//' | sed 's/[\x01-\x1F\x7F]//g' | sed 's/\[0m//g' | sed 's/\[.*\]//'}\
[${execi 5 sensors | grep 'temp1' | cut -c16-22}]
${cpugraph cpu0 40,340 52ff00 6edd21}
CPU 1${goto 70}${cpu cpu1}%${goto 100}${cpubar 8,width_cpu_bar cpu1}
CPU 2${goto 70}${cpu cpu2}%${goto 100}${cpubar 8,width_cpu_bar cpu2}
CPU 3${goto 70}${cpu cpu3}%${goto 100}${cpubar 8,width_cpu_bar cpu3}
CPU 4${goto 70}${cpu cpu4}%${goto 100}${cpubar 8,width_cpu_bar cpu4}
Ad this is the result:
Another example:
As you can see the result looks good but the filling cpubars dont work properly and all 4 bars have the same filling, clearly seen in the last one where I have a 100% core load (CPU3) and his bar is not completely full.
Where am I wrong?
The cpu number comes before the height,width part, i.e. use
${cpubar cpu1 8,width_cpu_bar}

GREP to columns along with comma seperation

Im greping a bunch of files in a directory as below
grep -EIho 'abc|def' *|sort|uniq -c >>counts.csv
My output is
150 abc
130 def
What I need is Current date (-1) and the result of grep like below to be inserted to counts.csv
5/21/2018 150,130
grep..|sort|uniq -c
|awk -v d="$(date -d '1 day ago' +%D)" 'NR==1{printf "%s",d}{printf "%s",","$1;}END{print ""}'
will do it.
With your example data, it gives:
05/21/18,150,130

grep specific pattern from a log file

I am passing all my svn commit log messages to a file and want to grep only the JIRA issue numbers from that.
Some lines might have more than 1 issue number, but I want to grab only the first occurrence.
The pattern is XXXX-999 (number of alpha and numeric char is not constant)
Also, I don't want the entire line to be displayed, just the JIRA number, without duplicates. I use the following command but it didn't work.
Could someone help please?
cat /tmp/jira.txt | grep '^[A-Z]+[-]+[0-9]'
Log file sample
------------------------------------------------------------------------
r62086 | userx | 2015-05-12 11:12:52 -0600 (Tue, 12 May 2015) | 1 line
Changed paths:
M /projects/trunk/gradle.properties
ABC-1000 This is a sample commit message
------------------------------------------------------------------------
r62084 | usery | 2015-05-12 11:12:12 -0600 (Tue, 12 May 2015) | 1 line
Changed paths:
M /projects/training/package.jar
EFG-1001 Test commit
Output expected:
ABC-1000
EFG-1001
First of all, it seems like you have the second + in the wrong place, it should be at the end of [0-9] expression.
Second, I think all you need to do this is use the -o option to grep (to display only the matching portion of the line), then pipe the grep output through sort -u, like this:
cat /tmp/jira.txt | grep -oE '^[A-Z]+-[0-9]+' | sort -u
Although if it were me, I'd skip the cat step and just give the filename to grep, as so:
grep -oE '^[A-Z]+-[0-9]+' /tmp/jira.txt | sort -u
Six of one, half a dozen of the other, really.

Multiple counts in grep?

So I have a big log file where each line contains a date. I would like to count the number of lines containing each date.
I came up with an awful solution, consisting of manually typing each of the following commands:
grep -c "2014-01-01" big.log
grep -c "2014-01-02" big.log
grep -c "2014-01-03" big.log
I could also have written a small Python script, but that seems overkill. Is there a quicker / more elegant solution?
You can maybe use of a regex and then uniq -c to count the results.
See an example:
$ cat a
2014-01-03 aaa
2014-01-03 aaa
2014-01-02 aaa
2014-01-01 aaa
2014-01-04 aaa
hello
2014-01-01 aaa
And let's look for all the 2014-01-0X, being X a digit, and count them:
$ grep -o "2014-01-0[0-9]" a | sort | uniq -c
2 2014-01-01
1 2014-01-02
2 2014-01-03
1 2014-01-04
Note piping to sort is needed to make uniq -c work properly. You can see more info about it in my answer to what is the meaning of delimiter in cut and why in this command it is sorting twice?.
Borrowing fedorqui's sample date file - thanks #fedorqui :-)
awk '/2014/{x[$1]++} END{for (k in x) print x[k],k}' file
2 2014-01-01
1 2014-01-02
2 2014-01-03
1 2014-01-04
try this
grep '2014-01-01' big.log |wc -l
grep '2014-01-02' big.log |wc -l
grep '2014-01-03' big.log |wc -l
Hope this will solve ur prob

Resources