1. Quick search on command line?
Want to quickly search in your directories? For example, you want to search for
.Rfiles that contain a string"latent", and print out the results. You may hope to do something like:
lookfor "latent" ".R"Or you want to just look for the files without specifying the file type by something like:
lookfor "latent"Or you want to print page-by-page using
less
lookfor latent | less(the quotation marks aroundlatentare not needed)If achieved, this could speed up your debugging process when you need to find certain variable names or keywords that you identified as useful.
1.1. Back-story
Here is an excellent solution I have been using (see more explanation at the end):
One line of code that have saved lots of time cumulatively: search for pattern $1 in files that end with $2. Thanks @rafalab for sharing this sometime ago!
— Zhenke Wu (吴振科) (@ZhenkeWu) April 11, 2019
19:31:10 ~/bin
$ more lookfor
#!/bin/bash
rg --no-heading -i "$1" --iglob \*$2
This was motivated by Rafa Irizarry who was my then-Hopkins professor and taught me 1st year linear regression class running R and compling files in Emacs (I had not been exposed to Unix before PhD):
Why did I wait 20+ years to write this? I've looked it up like 500 times!
— Rafael Irizarry (@rafalab) October 9, 2018
$ less ~/bin/lookfor
#!/bin/bash
grep -r --include=\*.$2 $1 ./ | less
Don't leave for tomorrow the Unix shell script you can write today!
As you can see by comparing the codes from the two tweets, I have used a different function rg which is faster, but both versions should work.
- Too many outputs? You may also append
"| less"when you use the command, e.g.,lookfor latent | less, to print only page-by-page whenlookforidentifies exceedingly many files or long files that contain the target stringlatent. However, by usingless, the results lose syntax highlighting. This is why I have no| lessby default to make it easier for my eyes when staring at the returned results.
2. Set things up
- Create the file at
/full/path/to/your/file, e.g., I created a file~/bin/lookforcontaining the following bash code:-
#!/bin/bash rg --no-heading -i "$1" --iglob \*$2
-
- Make the file excutable:
-
chmod +x /full/path/to/your/file
-
- Create a symbolic link to the file by following this. The symlink may be in a different location
/usr/local/bin/name_of_new_command. I created a symbolic link with the same name (does not have to be),lookfor.-
sudo ln -s /full/path/to/your/file /usr/local/bin/name_of_new_command
-
2.1. Example
For example, because I created the lookfor file at ~/bin/lookfor, I needed to replace /full/path/to/your/file with ~/bin/lookfor; I wanted to type lookfor to execute the file, so I replaced name_of_new_command with lookfor.
Note that we just created a symbolic in a different directory /usr/local/bin to the now executable file ~/bin/lookfor
Now you may type lookfor with appropriate arguments to do the quick search, save your time, and be less cranky!
3. More explanation (by GPT-4)
#!/bin/bash
rg --no-heading -i "$1" --iglob \*$2
This Bash script snippet utilizes rg, which is the command for Ripgrep, a fast search tool. The script performs a case-insensitive search for the pattern specified by $1 in files that match the glob pattern *$2.
Here’s a breakdown of the options used:
-
--no-heading: This option tells Ripgrep to omit the file names and just show the matching lines from each file. -
-i: This flag makes the search case-insensitive, meaning it will match both upper and lower case letters. -
$1: This is a placeholder for the first argument passed to the script. It represents the search pattern. -
--iglob \*$2: The--igloboption allows for case-insensitive file name matching.\*matches any number of any characters, and$2is a placeholder for the second argument to the script, which specifies the file extension or pattern to search within.
Overall, when you run this script with two arguments, it searches for the first argument (a text pattern) in all files that match the pattern given by the second argument (typically a file extension), without regard to case, and outputs the matching lines without file names.