grep to show things in the same file together - grep

When I do grep in this way on multiple files, I have:
$ grep "Sh\|Re" To_10pair_20140708_20160704_TIR_2.4_TSR_2.4_TP_1.0_SP_1.0/*/key_re*
To_10pair_20140708_20160704_TIR_2.4_TSR_2.4_TP_1.0_SP_1.0/QTNNSimplePredict_HLD_100,100_DOI_12_PG_12_WD_1e-05_SOT_10pair_20090601_20140707/key_results.txt:Sharpe ratio is: -1.6022503031
To_10pair_20140708_20160704_TIR_2.4_TSR_2.4_TP_1.0_SP_1.0/QTNNSimplePredict_HLD_100,100_DOI_12_PG_12_WD_1e-05_SOT_10pair_20090601_20140707/key_results.txt:Return rate is: -0.2357384
To_10pair_20140708_20160704_TIR_2.4_TSR_2.4_TP_1.0_SP_1.0/QTNNSimplePredict_HLD_100,100_DOI_12_PG_12_WD_4e-05_SOT_10pair_20090601_20140707/key_results.txt:Sharpe ratio is: 0.822358458311
To_10pair_20140708_20160704_TIR_2.4_TSR_2.4_TP_1.0_SP_1.0/QTNNSimplePredict_HLD_100,100_DOI_12_PG_12_WD_4e-05_SOT_10pair_20090601_20140707/key_results.txt:Return rate is: -0.0432811
Is it possible to have the result looks like
To_10pair_20140708_20160704_TIR_2.4_TSR_2.4_TP_1.0_SP_1.0/QTNNSimplePredict_HLD_100,100_DOI_12_PG_12_WD_1e-05_SOT_10pair_20090601_20140707/key_results.txt:
Sharpe ratio is: -1.6022503031
Return rate is: -0.2357384
To_10pair_20140708_20160704_TIR_2.4_TSR_2.4_TP_1.0_SP_1.0/QTNNSimplePredict_HLD_100,100_DOI_12_PG_12_WD_4e-05_SOT_10pair_20090601_20140707/key_results.txt:
Sharpe ratio is: 0.822358458311
Return rate is: -0.0432811

You could pipe the result to sed:
grep ...key_re* | sed -e '/:Sharpe/{h;s/:.*/:/;p;g;}' -e 's/[^:]*://'

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

remove word using "grep -v" exact match only

How can I do an exact match using grep -v?
For example: the following command
for i in 0 0.3 a; do echo $i | grep -v "0"; done
returns a. But I want it to return 0.3 a.
Using
grep -v "0\b"
is not working
for i in 0 0.3 a; do echo $i | grep -v "^0$"; done
You need to match the start and end of the string with ^ and $
So, we say "match the beginning of a line, the char 0 and then the end of the line.
$ for i in 0 0.3 a; do echo $i | grep -v "^0$"; done
0.3
a
The safest way for single-column entries is using awk. Normally, I would use grep with the -w flag, but since you want to exactly match an integer that could be part of a float, it is a bit more tricky. The <dot>-character makes it hard to use any of
grep -vw 0
grep -v '\b0\b'
grep -v '\<0\>'
The proposed solution also will only work on perfect lines, what if you have a lost space in front or after your zero. The line will fail. So the safest would be:
single column file:
awk '($1!="0")' file
multi-word file: (adopt the variable FS to fit your needs)
awk '{for(i=1;i<=NF;++i) if($i == "0") next}1' file

Line trimed to .. in gfsh command

I am running the below command in Unix box, it is gfsh command:
$GEMFIRE_HOME/bin/gfsh -e "connect --locator=$HOST[22710]" -e "list members" | grep "coordinator"
but, the catch is, if the returned members contain more than 100 characters then the output is .. for them , like below:
locator:103268:locator)<ec><v87><coordinato..
so the grep is failing. We know that we can change grep pattern, but we want to grep particular coordinator only.
Why does the output line get trimmed to ..?
I searched the docs, found below.
https://gemfire.docs.pivotal.io/91/geode/tools_modules/gfsh/configuring_gfsh.html
gfsh commands such as query produce output with wide columns that may
become misaligned and require manual reformatting to view the output.
If the output cannot fit in the available width of the terminal, gfsh
automatically trims the columns widths to fit. You can disable this
behavior by setting the gfsh environment variable GFSH.TRIMSCRWIDTH to
false.
Any suggestions?
I tried to get the only second pattern by awk '|', but still, the coordinator was a coordinator.
Tried cut also, didn't work.
$GEMFIRE_HOME/bin/gfsh -e "connect --locator=$HOST[22710]" -e "list members" | awk -F'|' '{print $2}'
103268:locator)<ec><v87><coordinato..
$GEMFIRE_HOME/bin/gfsh -e "connect --locator=$HOST[22710]" -e "list members" | awk -F'|' '{print $2}'
should be able to grep "coordinator" the output of gfsh and the output should not have .. in the lines.
If you add the following to your gfsh command, you should see the full output:
-e "set variable --name=APP_RESULT_VIEWER --value=x"
This is a workaround - the value x is arbitrary and this just avoids the default behavior you're seeing.

How do I 'grep -c' and avoid printing files with zero '0' count

The command 'grep -c blah *' lists all the files, like below.
% grep -c jill *
file1:1
file2:0
file3:0
file4:0
file5:0
file6:1
%
What I want is:
% grep -c jill * | grep -v ':0'
file1:1
file6:1
%
Instead of piping and grep'ing the output like above, is there a flag to suppress listing files with 0 counts?
SJ
How to grep nonzero counts:
grep -rIcH 'string' . | grep -v ':0$'
-r Recurse subdirectories.
-I Ignore binary files (thanks #tongpu, warlock).
-c Show count of matches. Annoyingly, includes 0-count files.
-H Show file name, even if only one file (thanks #CraigEstey).
'string' your string goes here.
. Start from the current directory.
| grep -v ':0$' Remove 0-count files. (thanks #LaurentiuRoescu)
(I realize the OP was excluding the pipe trick, but this is what works for me.)
Just use awk. e.g. with GNU awk for ENDFILE:
awk '/jill/{c++} ENDFILE{if (c) print FILENAME":"c; c=0}' *

How to find a pattern and surrounding content in a very large SINGLE line file?

I have a very large file 100Mb+ where all the content is on one line.
I wish to find a pattern in that file and a number of characters around that pattern.
For example I would like to call a command like the one below but where -A and -B are number of bytes not lines:
cat very_large_file | grep -A 100 -B 100 somepattern
So for a file containing content like this:
1234567890abcdefghijklmnopqrstuvwxyz
With a pattern of
890abc
and a before size of -B 3
and an after size of -A 3
I want it to return:
567890abcdef
Any tips would be great.
Many thanks.
You could try the -o option:
-o, --only-matching
Show only the part of a matching line that matches PATTERN.
and use a regular expression to match your pattern and the 3 preceding/following characters i.e.
grep -o -P ".{3}pattern.{3}" very_large_file
In the example you gave, it would be
echo "1234567890abcdefghijklmnopqrstuvwxyz" > tmp.txt
grep -o -P ".{3}890abc.{3}" tmp.txt
Another one with sed (you may need it on systems where GNU grep is not available):
sed -n '
s/.*\(...890abc...\).*/\1/p
' infile
Best way I can think of doing this is with a tiny Perl script.
#!/usr/bin/perl
$pattern = $ARGV[0];
$before = $ARGV[1];
$after = $ARGV[2];
while(<>) {
print $& if( /.{$before}$pattern.{$after}/ );
}
You would then execute it thusly:
cat very_large_file | ./myPerlScript.pl 890abc 3 3
EDIT: Dang, Paolo's solution is much easier. Oh well, viva la Perl!

Resources