“which” com uma pequena solução do tipo “grep”?

4
# 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.

    
por LanceBaynes 20.07.2011 / 19:29

8 respostas

4

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
    
por 20.07.2011 / 23:24
4

localize

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
    
por 20.07.2011 / 19:42
4

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
    
por 20.07.2011 / 20:52
2

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.

    
por 20.07.2011 / 20:01
2

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.

    
por 25.07.2011 / 10:55
0

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
    
por 24.07.2011 / 18:31
0

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
    
por 26.07.2011 / 14:01
0

Procure páginas man

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 .

    
por 14.10.2014 / 14:54