Vim ripgrep searching for pipe symbol - vim

Trying to search in vim using ripgrep :Rg for e.g. '||'.
Have tried:
:Rg --hidden --no-ignore '||'
:Rg --hidden --no-ignore '\|\|'
:Rg --hidden --no-ignore "||"
:Rg --hidden --no-ignore "\|\|"
But it just matches every column of every line.
According to the manual you can use --fixed-strings, but when I do
:Rg --fixed-strings --hidden --no-ignore '||'
:Rg --fixed-stringsssssssssssssssssss --hidden --no-ignore '||'
It still ignores any number of 's' to complain
1 || error: Found argument '--fixed-string' which wasn't expected, or isn't valid in this context
2 || Did you mean --fixed-strings?
3 ||
4 || USAGE:
5 ||
6 || rg [OPTIONS] PATTERN [PATH ...]
7 || rg [OPTIONS] [-e PATTERN ...] [-f PATTERNFILE ...] [PATH ...]
8 || rg [OPTIONS] --files [PATH ...]
9 || rg [OPTIONS] --type-list
10 || command | rg [OPTIONS] PATTERN
11 ||
12 || For more information try --help
13 ||
How do I use Vim Ripgrep to search for ||?

Related

grep between timestamps from logs in Unix

I have the following logs
2022-07-23T09:00:00,987 hi
2022-07-23T10:00:00,987 hi
2022-07-23T11:10:00,987 hi
2022-07-23T12:52:00,987 hi
2022-07-23T13:29:00,987 hi
2022-07-23T13:59:00,987 hi
I want to grep only the lines between 10 AM to 13:30 PM. Here is my command, but it doesn't retrieve the result as expected. Any ideas where it has to fix
sudo cat <path to my log file> | grep 'hi' | grep -E '2022-07-23T(10:[0-5][0-9]:[0-5][0-9]|13:30:00)'
awk is better tool for this than grep:
awk -F '[T,]' '$2 >= "10:00" && $2 <= "13:30" && /hi/' file
2022-07-23T10:00:00,987 hi
2022-07-23T11:10:00,987 hi
2022-07-23T12:52:00,987 hi
2022-07-23T13:29:00,987 hi
Here:
Using -F '[T,]' we delimit fields on T or , chars
awk -F '[T,]' '$2 >= "10:00" && $2 <= "13:30" does lexicological comparison of 2nd field with our data range
/hi/ search for hi in a line
Here is a grep solution using regex magic:
grep -E '^[^T]+T1([0-2]|3:([0-2][0-9]|30)):.* hi' file
2022-07-23T10:00:00,987 hi
2022-07-23T11:10:00,987 hi
2022-07-23T12:52:00,987 hi
2022-07-23T13:29:00,987 hi
RegEx Demo
RegEx Details:
^: Start
[^T]+:
T1: Match T followed by digit 1
([0-2]|3:([0-2][0-9]|30)): Match digits 0 to 2 to match time starting with 10 or 11 or 12. After alternation we match hour 13 followed by minutes 00 to 29 or 30
:.* hi: Match : followed by any string followed by a space and hi

I have multiple filenames with different versions . how to pick the highest numbered version from every filename

I have multiple filenames with different versions . how to pick the highest numbered version from every filename.
ganglia-3.7.2-2.el7.x86_64.rpm
ganglia-debuginfo-3.7.2-2.el7.x86_64.rpm
ganglia-devel-3.7.2-2.el7.x86_64.rpm
ganglia-gmetad-3.7.2-2.el7.x86_64.rpm
ganglia-gmond-3.7.2-2.el7.x86_64.rpm
ganglia-gmond-python-3.7.2-2.el7.x86_64.rpm
ganglia-web-3.7.1-2.el7.x86_64.rpm
ganglia-3.8.2-2.el7.x86_64.rpm
ganglia-debuginfo-3.8.2-2.el7.x86_64.rpm
ganglia-devel-3.8.2-2.el7.x86_64.rpm
ganglia-gmetad-3.8.2-2.el7.x86_64.rpm
ganglia-gmond-3.8.2-2.el7.x86_64.rpm
ganglia-gmond-python-3.8.2-2.el7.x86_64.rpm
ganglia-web-3.8.1-2.el7.x86_64.rpm\BMS-CEI2_BC-ADAP-19.04.1111-4_1.noarch.rpm
BMS-CEI2_BC-ADAP-19.04.1112-4_1.noarch.rpm
BMS-CEI2_BC-ADAP-20.04.1112-4_1.noarch.rpm
BMS-CEI2_BC-19.04.1111-4_1.noarch.rpm
BMS-CEI2_BC-19.04.1112-4_1.noarch.rpm
BMS-CEI2_BC-20.04.1112-4_1.noarch.rpm
glusterfs-cli-3.12.13-1.el9.x86_64.rpm
glusterfs-cli-3.12.13-1.el7.x86_64.rpm
glusterfs-cli-3.13.13-1.el7.x86_64.rpm
Output should be :
ganglia-3.8.2-2.el7.x86_64.rpm
ganglia-debuginfo-3.8.2-2.el7.x86_64.rpm
ganglia-devel-3.8.2-2.el7.x86_64.rpm
ganglia-gmetad-3.8.2-2.el7.x86_64.rpm
ganglia-gmond-3.8.2-2.el7.x86_64.rpm
ganglia-gmond-python-3.8.2-2.el7.x86_64.rpm
ganglia-web-3.8.1-2.el7.x86_64.rpm
glusterfs-cli-3.13.13-1.el7.x86_64.rpm
BMS-CEI2_BC-20.04.1112-4_1.noarch.rpm
BMS-CEI2_BC-ADAP-20.04.1112-4_1.noarch.rpm
i went through a method like taking prefixes and using ls -v command to get the versions ...
like
ganglia
ganglia-debuginfo
ganglia-dlevel
ganglia-web
.....
and used ls -v prefix* | tail -n 1 ..
i could get the prefect things but only for ganglia prefix i'm not able to get the perfect thing..please help me
I am able to get O/P
glusterfs-cli-3.13.13-1.el7.x86_64.rpm
BMS-CEI2_BC-20.04.1112-4_1.noarch.rpm
BMS-CEI2_BC-ADAP-20.04.1112-4_1.noarch.rpm
ganglia-debuginfo-3.8.2-2.el7.x86_64.rpm
ganglia-devel-3.8.2-2.el7.x86_64.rpm
ganglia-gmetad-3.8.2-2.el7.x86_64.rpm
ganglia-gmond-3.8.2-2.el7.x86_64.rpm
ganglia-gmond-python-3.8.2-2.el7.x86_64.rpm
ganglia-web-3.8.1-2.el7.x86_64.rpm
I am not able to get this ganglia-3.8.2-2.el7.x86_64.rpm in O/P
#!/bin/bash
ls -ltr *.rpm |awk '{print $9}' | sed '/^$/d' >> .ALLRPMNAMES.txt
# An associative array
declare -A names
# Iterate across the files, stripping version numbers and saving the name/prefix
for file in *.rpm
do
name=${file%%-[0-9]*} # Assume "-" and a non-zero digit marks the version
((names[$name]++))
done
echo " ${!names[#]}" >> RPMPREFIX.txt
sed -i 's/\s\+/\n/g' RPMPREFIX.txt
sed -i '/^$/d' RPMPREFIX.txt
while read line
do
ls -v $line* | tail -n 1 >> HighversionedRPMSALL.txt
done < RPMPREFIX.txt
grep -Fxvf HighversionedRPMSALL.txt .ALLRPMNAMES.txt | grep -v 'k.sh' >> LowVersionedRPMS.txt
As you probably already have figured out, a possible way to get the list of the package names is:
list_of_prefixes=$(ls -v *.rpm | sed 's/-[0-9].*$//' | uniq)
The assumption behind this is that a hyphen - in the filename followed by a digit indicates the beginning of the version string.
So, to get only the last version of each package, you could try:
for prefix in $list_of_prefixes; do
ls -rv $prefix-[0-9]* | head -n1
done
You will have noticed that, instead of listing the files in an ascending order and taking the last one with the command tail, I preferred to list the files in reverse order with the option -r for taking the first one with the command head -n1. I think this is faster.
Demo:
List of the files:
$ ls
BMS-CEI2_BC-19.04.1111-4_1.noarch.rpm
BMS-CEI2_BC-19.04.1112-4_1.noarch.rpm
BMS-CEI2_BC-20.04.1112-4_1.noarch.rpm
BMS-CEI2_BC-ADAP-19.04.1112-4_1.noarch.rpm
BMS-CEI2_BC-ADAP-20.04.1112-4_1.noarch.rpm
ganglia-3.7.2-2.el7.x86_64.rpm
ganglia-3.8.2-2.el7.x86_64.rpm
ganglia-debuginfo-3.7.2-2.el7.x86_64.rpm
ganglia-debuginfo-3.8.2-2.el7.x86_64.rpm
ganglia-devel-3.7.2-2.el7.x86_64.rpm
ganglia-devel-3.8.2-2.el7.x86_64.rpm
ganglia-gmetad-3.7.2-2.el7.x86_64.rpm
ganglia-gmetad-3.8.2-2.el7.x86_64.rpm
ganglia-gmond-3.7.2-2.el7.x86_64.rpm
ganglia-gmond-3.8.2-2.el7.x86_64.rpm
ganglia-gmond-python-3.7.2-2.el7.x86_64.rpm
ganglia-gmond-python-3.8.2-2.el7.x86_64.rpm
ganglia-web-3.7.1-2.el7.x86_64.rpm
ganglia-web-3.8.1-2.el7.x86_64.rpm
glusterfs-cli-3.12.13-1.el7.x86_64.rpm
glusterfs-cli-3.12.13-1.el9.x86_64.rpm
glusterfs-cli-3.13.13-1.el7.x86_64.rpm
List of the packages:
$ listofprefixes=$(ls -v | sed 's/-[0-9].*$//' | uniq)
$ echo "$listofprefixes"
BMS-CEI2_BC
BMS-CEI2_BC-ADAP
ganglia
ganglia-debuginfo
ganglia-devel
ganglia-gmetad
ganglia-gmond
ganglia-gmond-python
ganglia-web
glusterfs-cli
List of last version of each package:
$ for p in $listofprefixes ; do ls -rv $p-[0-9]* | head -n1 ; done
BMS-CEI2_BC-20.04.1112-4_1.noarch.rpm
BMS-CEI2_BC-ADAP-20.04.1112-4_1.noarch.rpm
ganglia-3.8.2-2.el7.x86_64.rpm
ganglia-debuginfo-3.8.2-2.el7.x86_64.rpm
ganglia-devel-3.8.2-2.el7.x86_64.rpm
ganglia-gmetad-3.8.2-2.el7.x86_64.rpm
ganglia-gmond-3.8.2-2.el7.x86_64.rpm
ganglia-gmond-python-3.8.2-2.el7.x86_64.rpm
ganglia-web-3.8.1-2.el7.x86_64.rpm
glusterfs-cli-3.13.13-1.el7.x86_64.rpm
The entry ganglia-3.8.2-2.el7.x86_64.rpm is present.

Extract string before and after keyword using special character as start and end positions to be extracted in Linux

I have a log file like the following one. It does not have any consistency in terms of format. I have been able to remove all non necessary new lines so that each Warning is in a new line.
Warning: Variants 'aaa8212' and 'bbb2388_ver2' have the same position.
Warning: Variants 'ccc9186' and
'ddd225581' have the same position.
Warning: Variants 'e223513'
and 'ffff13855' have the same position.
Warning: Variants 'gg08395' and 'hhh34224' have the
same
position.
Warning: Variants 'iii454353428' and 'jjjjjj82428' have the same
position.
Warning: 6000 het. haploid genotypes present (see Tet_merged.hh ); many
commands treat these as missing.
Warning: Nonmissing nonmale Y chromosome genotype(s) present; many commands
treat these as missing.
My output looks like this:
Warning: Variants 'aaa8212' and 'bbb2388_ver2' have the same position.
Warning: Variants 'ccc9186' and 'ddd225581' have the same position.
Warning: Variants 'e223513' and 'ffff13855' have the same position.
Warning: Variants 'gg08395' and 'hhh34224' have the same position.
Warning: Variants 'iii454353428' and 'jjjjjj82428' have the same position.
In order to get this output I have used the following command:
cat Test_lines.txt | grep "'" | awk '/position\.$/ {print; next} {printf "%s ", $0}' Test_lines.txt
First, I extracted the Warning lines containing a single quote (the ones I'm interested in) and afterwards I printed only those lines ending in "position." and I removed all other extra new line characters.
However, I would like to extract for each Warning line the string between single quotes before and after the " and " string. In this case the desired output should be:
'aaa8212' and 'bbb2388_ver2'
'ccc9186' and 'ddd225581'
'e223513' and 'ffff13855'
'gg08395' and 'hhh34224'
'iii454353428' and 'jjjjjj82428'
For this last purpose, I have tried to use the following syntax:
cat Test_lines.txt | grep "'" | grep -o -P '.{0,3} and .{0,4}'
But this syntax relies on positions and not on delimiters such as the single quote. Is there any way I can substitute a specific positions for the nth presence of a specific delimiter, in this case the single quote?
Thank you very much,
Best,
Yatrosin
With single GNU awk command:
awk -v RS='\\<position\\.' \
'/\047/{ gsub(/^[^\047]+|\n+|[^\047]+$/, ""); print $0 }' Test_lines.txt
The output:
'aaa8212' and 'bbb2388_ver2'
'ccc9186' and 'ddd225581'
'e223513' and 'ffff13855'
'gg08395' and 'hhh34224'
'iii454353428' and 'jjjjjj82428'
You can pass the awk's output to grep -o "'.*'" , so the commands would be:
cat Test_lines.txt | grep "'" |
awk '/position\.$/ {print; next} {printf "%s ", $0}' Test_lines.txt
cat Test_lines.txt | grep -o "'.*'"
Full Example:
echo "Warning: Variants 'aaa8212' and 'bbb2388_ver2' have the same position.
Warning: Variants 'ccc9186' and 'ddd225581' have the same position.
Warning: Variants 'e223513' and 'ffff13855' have the same position.
Warning: Variants 'gg08395' and 'hhh34224' have the same position.
Warning: Variants 'iii454353428' and 'jjjjjj82428' have the same position.
" -n | grep "'" | awk '/position\.$/ {print; next} {printf "%s ", $0}' | grep -o "'.*'"
Output:
'aaa8212' and 'bbb2388_ver2'
'ccc9186' and 'ddd225581'
'e223513' and 'ffff13855'
'gg08395' and 'hhh34224'
'iii454353428' and 'jjjjjj82428'

Count occurence of character in files

I want to count all $ characters in each file in a directory with several subdirectories.
My goal is to count all variables in a PHP project. The files have the suffix .php.
I tried
grep -r '$' . | wc -c
grep -r '$' . | wc -l
and a lot of other stuff but all returned a number that can not match. In my example file are only four $.
So I hope someone can help me.
EDIT
My example file
<?php
class MyClass extends Controller {
$a;$a;
$a;$a;
$a;
$a;
To recursively count the number of $ characters in a set of files in a directory you could do:
fgrep -Rho '$' some_dir | wc -l
To include only files of extension .php in the recursion you could instead use:
fgrep -Rho --include='*.php' '$' some_dir | wc -l
The -R is for recursively traversing the files in some_dir and the -o is for matching part of the each line searched. The set of files are restricted to the pattern *.php and file names are not included in the output with -h, which may otherwise have caused false positives.
For counting variables in a PHP project you can use the variable regex defined here.
So, the next will grep all variables for each file:
cd ~/my/php/project
grep -Pro '\$[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*' .
-P - use perlish regex
-r - recursive
-o - each match on separate line
will produce something like:
./elFinderVolumeLocalFileSystem.class.php:$path
./elFinderVolumeLocalFileSystem.class.php:$path
./elFinderVolumeMySQL.class.php:$driverId
./elFinderVolumeMySQL.class.php:$db
./elFinderVolumeMySQL.class.php:$tbf
You want count them, so you can use:
$ grep -Proc '\$[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*' .
and will get the count of variables in each file, like:
./connector.minimal.php:9
./connector.php:9
./elFinder.class.php:437
./elFinderConnector.class.php:46
./elFinderVolumeDriver.class.php:1343
./elFinderVolumeFTP.class.php:577
./elFinderVolumeFTPIIS.class.php:63
./elFinderVolumeLocalFileSystem.class.php:279
./elFinderVolumeMySQL.class.php:335
./mime.types:0
./MySQLStorage.sql:0
When want count by file and by variable, you can use:
$ grep -Pro '\$[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*' . | sort | uniq -c
for getting result like:
17 ./elFinderVolumeLocalFileSystem.class.php:$target
8 ./elFinderVolumeLocalFileSystem.class.php:$targetDir
3 ./elFinderVolumeLocalFileSystem.class.php:$test
97 ./elFinderVolumeLocalFileSystem.class.php:$this
1 ./elFinderVolumeLocalFileSystem.class.php:$write
6 ./elFinderVolumeMySQL.class.php:$arc
3 ./elFinderVolumeMySQL.class.php:$bg
10 ./elFinderVolumeMySQL.class.php:$content
1 ./elFinderVolumeMySQL.class.php:$crop
where you can see, than the variable $write is used only once, so (maybe) it is useless.
You can also count per variable per whole project
$ grep -Proh '\$[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*' . | sort | uniq -c
and will get something like:
13 $tree
1 $treeDeep
3 $trg
3 $trgfp
10 $ts
6 $tstat
35 $type
where you can see, than the $treeDeep is used only once in a whole project, so it is sure useless.
You can achieve many other combinations with different grep, sort and uniq commands..

grep: show lines surrounding each match

How do I grep and show the preceding and following 5 lines surrounding each matched line?
For BSD or GNU grep you can use -B num to set how many lines before the match and -A num for the number of lines after the match.
grep -B 3 -A 2 foo README.txt
If you want the same number of lines before and after you can use -C num.
grep -C 3 foo README.txt
This will show 3 lines before and 3 lines after.
-A and -B will work, as will -C n (for n lines of context), or just -n (for n lines of context... as long as n is 1 to 9).
ack works with similar arguments as grep, and accepts -C. But it's usually better for searching through code.
grep astring myfile -A 5 -B 5
That will grep "myfile" for "astring", and show 5 lines before and after each match
ripgrep
If you care about the performance, use ripgrep which has similar syntax to grep, e.g.
rg -C5 "pattern" .
-C, --context NUM - Show NUM lines before and after each match.
There are also parameters such as -A/--after-context and -B/--before-context.
The tool is built on top of Rust's regex engine which makes it very efficient on the large data.
I normally use
grep searchstring file -C n # n for number of lines of context up and down
Many of the tools like grep also have really great man files too. I find myself referring to grep's man page a lot because there is so much you can do with it.
man grep
Many GNU tools also have an info page that may have more useful information in addition to the man page.
info grep
Use grep
$ grep --help | grep -i context
Context control:
-B, --before-context=NUM print NUM lines of leading context
-A, --after-context=NUM print NUM lines of trailing context
-C, --context=NUM print NUM lines of output context
-NUM same as --context=NUM
If you search code often, AG the silver searcher is much more efficient (ie faster) than grep.
You show context lines by using the -C option.
Eg:
ag -C 3 "foo" myFile
line 1
line 2
line 3
line that has "foo"
line 5
line 6
line 7
Search for "17655" in /some/file.txt showing 10 lines context before and after (using Awk), output preceded with line number followed by a colon. Use this on Solaris when grep does not support the -[ACB] options.
awk '
/17655/ {
for (i = (b + 1) % 10; i != b; i = (i + 1) % 10) {
print before[i]
}
print (NR ":" ($0))
a = 10
}
a-- > 0 {
print (NR ":" ($0))
}
{
before[b] = (NR ":" ($0))
b = (b + 1) % 10
}' /some/file.txt;
Let's understand using an example.
We can use grep with options:
-A 5 # this will give you 5 lines after searched string.
-B 5 # this will give you 5 lines before searched string.
-C 5 # this will give you 5 lines before & after searched string
Example.
File.txt contains 6 lines and following are the operations.
[abc#xyz]~/% cat file.txt # print all file data
this is first line
this is 2nd line
this is 3rd line
this is 4th line
this is 5th line
this is 6th line
[abc#xyz]~% grep "3rd" file.txt # we are searching for keyword '3rd' in the file
this is 3rd line
[abc#xyz]~% grep -A 2 "3rd" file.txt # print 2 lines after finding the searched string
this is 3rd line
this is 4th line
this is 5th line
[abc#xyz]~% grep -B 2 "3rd" file.txt # Print 2 lines before the search string.
this is first line
this is 2nd line
this is 3rd line
[abc#xyz]~% grep -C 2 "3rd" file.txt # print 2 line before and 2 line after the searched string
this is first line
this is 2nd line
this is 3rd line
this is 4th line
this is 5th line
Trick to remember options:
-A  → A means "after"
-B  → B means "before"
-C  → C means "in between"
I do it the compact way:
grep -5 string file
That is the equivalent of:
grep -A 5 -B 5 string file
Here is the #Ygor solution in awk
awk 'c-->0;$0~s{if(b)for(c=b+1;c>1;c--)print r[(NR-c+1)%b];print;c=a}b{r[NR%b]=$0}' b=3 a=3 s="pattern" myfile
Note: Replace a and b variables with number of lines before and after.
It's especially useful for system which doesn't support grep's -A, -B and -C parameters.
Grep has an option called Context Line Control, you can use the --context in that, simply,
| grep -C 5
or
| grep -5
Should do the trick
$ grep thestring thefile -5
-5 gets you 5 lines above and below the match 'thestring' is equivalent to -C 5 or -A 5 -B 5.

Resources