No zsh:
echo $path/mkdi*(N)
Em outras conchas, para consumo humano:
set -f; IFS=:
for x in $PATH; do set +f; ls $x/mkdi* 2>/dev/null; done
# which mkdir
/bin/mkdir
# which mkdi
#
Como posso obter o caminho do binário da seguinte forma: mkdir
sem saber o nome do arquivo binário? (comando). Então, which mkdi
produziria o /bin/mkdir
também.
locate mkdi
Atualização: isso restringirá a saída aos arquivos no $PATH
locate mkdi |
while read filename; do
[[ ":$PATH:" == *:$(dirname $filename):* ]] && echo $filename
done
run-parts
pode fazer exatamente isso, considerando os parâmetros certos. Aqui está um wrapper simples que eu escrevi em torno dele:
#!/bin/bash
# swhich - search the path (like which) but with support for regular expressions
# "swhich '.*ch$' '^wh'" to find all in path ending with 'ch' and all starting with 'wh'
set -f; IFS=:
for all in $PATH
do
set +f
for each in "$@"
do
run-parts --list --regex "$each" "$all"
done
done
Se você não tiver certeza do executável que está procurando, também poderá consultar o banco de dados man
com o comando apropos
, por exemplo, apropos dir
listará os comandos normalmente usados ao trabalhar com diretórios, find o comando que você precisa, passe para which
como normal.
compgen
é um BASH interno que gera conclusões para uma determinada string. A opção -c
conclui os nomes dos comandos no caminho:
$ compgen -c mkd
mkdirhier
mkdir
mkdiskimage
mkdir
Nota: mkdir
está aqui duas vezes porque está em / bin e / usr / bin no meu sistema.
A conclusão programável é legal. Ele permitirá que você faça coisas assim:
$ shopt -s progcomp; complete -c which # set up progcomp
$ which mkd<ALT-*>
$ which mkdir mkdirhier mkdiskimage
... o que pode estar mais perto do que você está procurando.
Aqui está outra forma de obter o caminho binário (se o prefixo for conhecido) usando printf
e nome do arquivo globbing no Bash.
mywhich() (
bin="$1"
PATH="${PATH// /\ }" # escape spaces
#eval 'echo "$PATH"'
#printf '%s\n' "printf '%s\n' ${PATH//://${bin}* }/${bin}*" | bash -s -f -O nullglob --
result="$(printf '%s\n' "printf '%s\n' ${PATH//://${bin}* }/${bin}*" | bash -s +f -O nullglob --)"
[[ -n "$result" ]] && printf '%s\n' "$result" && exit 0 || exit 1
)
mywhich mkdi
A abordagem a seguir lista todos os caminhos completos para os binários correspondentes usando somente Bash builtins:
# mywhich version 2
mywhich() ( # using a subshell the parent shell is not affected by set & shopt, ...
bin="$1"
set +f
shopt -s nullglob
IFS=':' read -a array <<<"$PATH"
IFS=""
result="$( printf '%s\n' ${array[@]/%//${bin}*} )"
[[ -n "$result" ]] && printf '%s\n' "$result" && exit 0 || exit 1
)
mywhich mkdi
Como você está pesquisando comandos, em vez de combinar os nomes dos binários de comando, você poderia combinar nomes de páginas man como uma alternativa; Isso pode fazer sentido porque man
já fornece esse recurso por padrão:
$ man --sections=1,8 --where --all --regex '^mkdi'
/usr/share/man/man1/mkdir.1.gz
/usr/share/man/man1/mkdirhier.1.gz
/usr/share/man/man1/mkdiskimage.1.gz
Usando sed
para extrair apenas os nomes dos comandos:
$ man --sections=1,8 --where --all --regex '^mkdi' | \
sed -r 's/.*\/([^/]+)\.[^.]+\.[^.]+$//'
mkdir
mkdirhier
mkdiskimage
E executando which
para os nomes dos comandos também:
$ man --sections=1,8 --where --all --regex '^mkdi' | \
sed -r 's/.*\/([^/]+)\.[^.]+\.[^.]+$//' | xargs which
/bin/mkdir
/usr/bin/mkdirhier
/usr/bin/mkdiskimage
Os padrões são expressões regulares, portanto, o ^
é adicionado para corresponder apenas no início do nome.
Para uma sintaxe de padrão semelhante a um shell glob, substitua --regex
by --wildcard
,
como man ... --wildcard 'mkdi*' | ...
.
Como uma função shell:
whichmatch() {
man --sections=1,8 --where --all --regex "$@" |
sed -r 's/.*\/([^/]+)\.[^.]+\.[^.]+$//' |
xargs which
}
usado como:
whichmatch '^mkdi'
Para correspondência aproximada de nomes de comandos, whichman
pode ser usado no lugar de man
.