Hielke Walinga
Hielke Walinga

Reputation: 2845

How to use "which" with regex, or other ways to find a command in the $PATH

I am looking for a command, and I want to use regex for finding it.

So, something like this

>>> which -a "e?grep"
/bin/grep
/bin/egrep

Any workarounds are also appreciated.

Upvotes: 1

Views: 258

Answers (3)

badc0de
badc0de

Reputation: 177

As stated in another question you can list all commands and functions using compgen, thus making the task a trivial matter of which regex engine or command do you want to use.

An example listing EVERYTHING you could possible run:

$ compgen -A function -abck | grep '.*grep.*' egrep fgrep grep egrep fgrep grep lzfgrep fgrep lzgrep zstdgrep zfgrep bzgrep plugreport pcregrep lzegrep msggrep grep pgrep zegrep zgrep egrep xzegrep zipgrep xzgrep xzfgrep pcre2grep orc-bugreport ptargrep ptargrep

See mentioned question for further information and other available listings. Credit to user Rahul Patil.

Upvotes: 1

Socowi
Socowi

Reputation: 27225

This answer extends Kamil Cuk's idea. Improvements:

  • Support $PATH containing spaces and linebreaks.
  • Do not search subdirectories of $PATH.

Script:

#! /bin/bash

# Search a program using an extended regex.
# usage: thisScript extendedRegex 

IFS=: read -d '' -a patharray < <(printf %s "$PATH")

find "${patharray[@]}" -maxdepth 1 -type f -executable \
     -regextype egrep -regex ".*/$1"

Your regex must match the whole command name, similar to grep -x.

Possible changes:

  • To also match parts of command names, change -regex ".*/$1" to -regex ".*/.*$1.*". However, ^ and $ will not work with this change.
  • For case-insensitive search, change -regex to -iregex.
  • To use another regex style, change egrep accordingly. find -regextype help prints all supported regex types.
  • To print only the command names instead of full paths, append -printf '%f\n'.

Upvotes: 0

KamilCuk
KamilCuk

Reputation: 141145

Just search in $PATH variable:

find $(tr : ' ' <<<"$PATH") -type f -executable | egrep "/[e]?grep$"

First I find all the executable files in PATH directories, then I egrep with your regex.
The command outputs:

/usr/bin/egrep
/usr/bin/grep

Upvotes: 1

Related Questions