это вполне легко можно реализовать на самом баше в несколько строк, если нужен именно руби то можете просто взять за основу как отправную точку для своей реализации
список всех программ расположенных в $PATH
$ ls ${PATH//:/ } |awk 'NF && !/:$/'
список, а точнее описание, встроенных(
builtin) команд в оболочку
bash можно посмотреть с помощью команды
help
$ help
но думаю правильнее будет использовать
type для определения типа команды
$ type -t rg
file
$ type -t cd
builtin
$ type --help
...
-t output a single word which is one of `alias', `keyword',
`function', `builtin', `file' or `', if NAME is an alias,
shell reserved word, shell function, shell builtin, disk file,
or not found, respectively
тип
file по сути это чисто внешние программы, а
builtin - внутреннии, на счет остальных могут быть нюансы, то есть при проверке через
type оставляем тока те утилиты которые возвращают
file.
В итоге мы можем сгенерировать список(
file.txt) чисто внешних программ из тех что лежат в
$PATH:
$ for i in $(ls ${PATH//:/ } |awk 'NF && !/:$/');do [[ $(type -t $i) == "file" ]] && echo $i;done > file.txt
Допустим у нас есть файл
test.txt с историей команд:
sudo ls | awk '!($NF ~ /\.[a-z]+$/)'
for i in ~/*; do echo $(locate -c -r $i) $i; done | pv | sort -nr | bcat -t
for f in *.zip; do unzip $f; done
RACK_HANDLER=falcon rails s
тогда:
$ grep -o -w -n -f file.txt test.txt
1:sudo
1:awk
2:pv
2:sort
3:zip
3:unzip
единственный недостаток это каждое совпадение пишет с новой строки, исправляем с помощью awk:
$ grep -o -w -n -f file.txt test.txt |awk -F: '{if($1!=i){printf $2" "}else{print $2};i=$1}'
sudo awk
pv sort
zip unzip
если сравнивать с вашим шаблоном:
sudo ls awk
pv sort bcat
unzip
rails
то мы видим что нету
ls это из за того что, например, у меня это
alias основанный на
exa - внешней программе, хотя с таким же успехом это могла быть внутренняя программа, та же
ls с подобранными ключами, но её бы тоже здесь бы не отобразило, в общем если алиасы включать в вывод то по идее их тоже нужно будет анализировать в отдельном обработчике.
также естественно что иногда будут происходить косяки как например тут с
zip при анализе строки
for f in *.zip; do unzip $f; done
zip тут не выступает в роли программы, но это всё же слово которое совпало с нашим списком утилит.
bcat и
rails не вывело так как данных программ не установленно.
в общем если кратко то всё это реализовывается в два однострочника на bash:
$ for i in $(ls ${PATH//:/ } |awk 'NF && !/:$/');do [[ $(type -t $i) == "file" ]] && echo $i;done > file.txt
$ grep -o -w -n -f file.txt test.txt |awk -F: '{if($1!=i){printf $2" "}else{print $2};i=$1}'