ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
Here's what I'm trying to accomplish:
Write a quick one-liner for BASH, that will attempt to find the desired binary/executable under paths listed in $PATH environment variable.
I need this, because "whereis" and "which" commands do not support wildcards and there are many handy commands/utilities with names derived from other commands/utilities (e.g. "grep", "egrep", "diff" "sdiff").
My approach was to extract paths from $PATH and transform them in a way appropriate for passing to a for loop:
Then run find with the desired expression once for every path in the list (a textbook for loop):
Quote:
[root@centos-pc1 ~]# for x in `echo $PATH | sed s/:/\\n/g | grep -v root`; do find $x -name "*diff"; done
[root@centos-pc1 ~]#
stderr output, not suppressed by a pipe:
Quote:
[root@centos-pc1 ~]# for x in `echo $PATH | sed s/:/\\n/g`; do find $x -name "*diff"; done
find: /usr/kerberos/sbinn/usr/kerberos/binn/usr/local/sbinn/usr/local/binn/sbinn/binn/usr/sbinn/usr/binn/root: No such file or directory
[root@centos-pc1 ~]#
"sbinn", "binn"... Can you explain how or why these extra n-s appeared at the end of each path?
Here's another way of receiving an analogues set of paths:
Quote:
[root@centos-pc1 ~]# find / -maxdepth 3 -type d | grep bin | grep -v var | cat -A
/sbin$
/bin$
/usr/local/sbin$
/usr/local/bin$
/usr/sbin$
/usr/bin$
/usr/kerberos/sbin$
/usr/kerberos/bin$
When used with a for loop, the approach works like a charm:
Quote:
[root@centos-pc1 ~]# for x in `find / -maxdepth 3 -type d | grep bin | grep -v var`; do find $x -name "*diff"; done
/usr/sbin/clockdiff
/usr/bin/gendiff
/usr/bin/sdiff
/usr/bin/bzdiff
/usr/bin/vimdiff
/usr/bin/zdiff
/usr/bin/diff
/usr/bin/ptardiff
/usr/bin/sediff
Though, this solution is rugged, clearly buggy and does not fully solve the initial problem.
Thanks in advance.
Click here to see the post LQ members have rated as the most helpful post in this thread.
Some offtopic. For people looking for such commands they do not known name, but known similar names or tags there is a command "apropos". For example:
Code:
$ apropos -s 1 grep
bzegrep (1) - search possibly bzip2 compressed files for a regular expression
bzfgrep (1) - search possibly bzip2 compressed files for a regular expression
bzgrep (1) - search possibly bzip2 compressed files for a regular expression
egrep (1) - print lines matching a pattern
fgrep (1) - print lines matching a pattern
grep (1) - print lines matching a pattern
pgrep (1) - look up or signal processes based on name and other attributes
rgrep (1) - print lines matching a pattern
xzegrep (1) - search compressed files for a regular expression
xzfgrep (1) - search compressed files for a regular expression
xzgrep (1) - search compressed files for a regular expression
zegrep (1) - search possibly compressed files for a regular expression
zfgrep (1) - search possibly compressed files for a regular expression
zgrep (1) - search possibly compressed files for a regular expression
zipgrep (1) - search files in a ZIP archive for lines matching a pattern
$ apropos -s 1 diff
sg (1) - execute command as different group ID
vimdiff (1) - edytuj dwie, trzy lub cztery wersje pliku w Vimie i zobacz różnice
kdiff3 (1) - compares two or three input files or directories
bzdiff (1) - compare bzip2 compressed files
diff (1) - compare files line by line
diff3 (1) - compare three files line by line
kompare (1) - a KDE GUI for viewing differences between files
xzcmp (1) - compare compressed files
ndiff (1) - Utility to compare the results of Nmap scans
patch (1) - apply a diff file to an original
ptardiff (1) - program that diffs an extracted archive against an unextracted one
sdiff (1) - side-by-side merge of file differences
xzdiff (1) - compare compressed files
zdiff (1) - compare compressed files
Note that this will list the paths if $THE_PROGRAM is empty, which hopefully isn't that big of a deal. It also won't work if $PATH only has one directory, but hey, you asked for one line. It works with all bash wildcards and expansions, e.g. THE_PROGRAM='*diff'.
Kevin Barry
unSpawn, three backslashes instead of two indeed worked. Wicked... :-)
[root@centos-pc1 ~]# for x in `echo $PATH | sed s/:/\\\n/g`; do find $x -name "*diff"; done 2>/dev/null
/usr/sbin/clockdiff
/usr/bin/tiffdiff
/usr/bin/interdiff
/usr/bin/ptardiff
/usr/bin/pdiff
/usr/bin/unwrapdiff
/usr/bin/rcsdiff
/usr/bin/diff
/usr/bin/splitdiff
/usr/bin/pamtohdiff
/usr/bin/dehtmldiff
/usr/bin/combinediff
/usr/bin/sdiff
/usr/bin/zdiff
/usr/bin/vimdiff
/usr/bin/editdiff
/usr/bin/recountdiff
/usr/bin/filterdiff
/usr/bin/ibtopodiff
/usr/bin/sgmldiff
/usr/bin/grepdiff
/usr/bin/gendiff
/usr/bin/lsdiff
/usr/bin/rediff
/usr/bin/fixcvsdiff
/usr/bin/bzdiff
/usr/bin/flipdiff
/usr/bin/espdiff
/usr/bin/sediff
[root@centos-pc1 ~]#
Quote:
Some offtopic. For people looking for such commands they do not known name, but known similar names or tags there is a command "apropos".
eSelix, "apropos" and "whatis" turned out to be amazingly useful tools. But instead of searching in $PATH, they query the man pages, extracting paths with a similar trick:
(A line from “cat /usr/bin/apropos” output)
That regular expression replaces the colons in $PATH with spaces. You can try it and see:
Yeah Diantre, it was clear what the purpose of ${PATH//:/ } was - to replace all occurrences of “:” with “ “, in value of variable $PATH. Though, the syntax (or how it was doing this) was unclear, so I enquired about it. The closest thing it reminded me of was a regular expressions... a rather odd one indeed. Well, turns out it’s not a regexp after all.
Quote:
Just for clarification, it is parameter substitution. The reason I make the difference is because it uses globbing and not regex.
grail, thanks, this is exactly what I was interested in. I will look closer at parameter substitution and globbing.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.