Comment créer une phrase extensible spéciale en bash?

12

Je me retrouve à faire <command> --help | grep <feature>très très souvent tous les jours. Je me demandais s'il était possible de créer quelque chose comme ^^ça "--help | grep"et ensuite je fais ceci:

ls ^^ size

Cela exécuterait ce qui suit:

ls --help | grep size
yukashima huksay
la source

Réponses:

17

Vous pouvez utiliser une fonction bash pour cela:

Mettez ce qui suit dans votre ~ / .bashrc:

qh() {
    type -all "$1" ; { man "$1" || "$1" --help ;} | egrep -i -- "$2"
}

Lorsque vous enregistrez votre bashrc faire, source ~/.bashrcvous pouvez faire:

$ qh ls size
      --block-size=SIZE      scale sizes by SIZE before printing them; e.g.,
                               '--block-size=M' prints sizes in units of
  -h, --human-readable       with -l and/or -s, print human readable sizes
  -s, --size                 print the allocated size of each file, in blocks
  -S                         sort by file size, largest first
      --sort=WORD            sort by WORD instead of name: none (-U), size (-S),
  -T, --tabsize=COLS         assume tab stops at each COLS instead of 8
tgwtdt
la source
1
vous devez citer 1 $ et 2 $. Je changerais cela en: qh () { type -all "$1" ; { "$1" --help || man "$1" ;} | egrep -i -- "$2" ;} # d' où vous pouvez: taille QH ls, ls QH « quelque chose | autre » , etc. le (facultatif) type -all "$1"ajouter aussi les informations sur 1 $: il dit que si vous lancerons un alias, une fonction, un etc, et il donne des informations de l'homme "$ 1" si la commande $ 1 n'avait pas l'option "--help" (cela arrive parfois)
Olivier Dulac
1
@OlivierDulac Pouvez-vous s'il vous plaît expliquer un peu plus sur le type -all "$ 1"? Dans quel cas sera-ce une nécessité?
tgwtdt
Ma version de type (kubuntu 16.04) est au courant -a, mais ne dit rien sur -lou -all, mais la fonction fonctionne.
Joe
15

Avec zsh, vous utiliseriez un alias global :

$ alias -g '^^=--help|grep --color -i'
$ ls ^^ size
     --block-size=SIZE      scale sizes by SIZE before printing them; e.g.,
                              '--block-size=M' prints sizes in units of
                              1,048,576 bytes; see SIZE format below
 -h, --human-readable       with -l and/or -s, print human readable sizes
 -s, --size                 print the allocated size of each file, in blocks
 -S                         sort by file size, largest first
     --sort=WORD            sort by WORD instead of name: none (-U), size (-S),
 -T, --tabsize=COLS         assume tab stops at each COLS instead of 8
The SIZE argument is an integer and optional unit (example: 10K is 10*1024)

Avec bash, vous pourrez peut-être utiliser l'expansion de l'historique, qui se produit suffisamment tôt dans l'analyse syntaxique du shell pour pouvoir remplacer un canal:

  1. Amorcez l'histoire avec le texte que vous souhaitez remplacer et un caractère spécial que vous n'utiliserez probablement pas autrement (comme £ici qui se trouve sur mon clavier):

     $ --help $(: £)|grep
     bash: --help: command not found
     Usage: grep [OPTION]... PATTERN [FILE]...
     Try 'grep --help' for more information.
    
  2. Ensuite, utilisez l'expansion de l'historique pour récupérer cela:

    $ ls !?£? size
    ls --help $(: £)|grep size
         --block-size=SIZE  scale sizes by SIZE before printing them; e.g.,
                              '--block-size=M' prints sizes in units of
     -h, --human-readable   with -l and/or -s, print human readable sizes
     -s, --size             print the allocated size of each file, in blocks
     -S                     sort by file size, largest first
         --sort=WORD        sort by WORD instead of name: none (-U), size (-S),
     -T, --tabsize=COLS     assume tab stops at each COLS instead of 8
    

Ou vous pourriez avoir readlinedéveloppé --help|grepune touche ou une séquence de touches. Pour que cela s'applique bashuniquement (et pas à d'autres applications comme l' gdbutilisation de readline), vous pouvez utiliser la bindcommande bash builtin qui est bashl'API de configuration readline, par exemple dans votre ~/.bashrc:

bind '"^^": "--help|grep "'

Ou ajoutez à votre ~/.inputrc(fichier de configuration de readline):

$if Bash
"^^": "--help|grep "
$endif

(il y a d'autres shells comme rcou esqui utilisent readline et où faire cette liaison pourrait avoir du sens mais AFAICT, ils ne définissent pas la rl_readline_namevariable avant l'appel readline, vous ne pourrez donc pas leur ajouter des $ifinstructions (ils s'afficheraient othercomme toutes les applications) qui utilisent readline sans leur dire le nom de leur application)).

Notez que vous devez entrer la seconde ^dans la demi-seconde (par défaut) après la première pour que la substitution se produise.

Stéphane Chazelas
la source
Pouvez-vous expliquer un peu plus la solution readline?! où dois-je ajouter cette liaison? sur quelles applications cette liaison se développera-t-elle?
yukashima huksay
@yukashimahuksay, voir edit
Stéphane Chazelas
8

Vous pouvez utiliser des liaisons readline:

ajouter une ligne comme

"^^": "--help | grep "

à votre ~ / .inputrc

Appuyez ensuite sur ^ X ^ R dans votre terme, et la liaison sera activée.

La saisie ls ^^entraînera maintenant ls --help | grep.

Alex Stragies
la source
J'ai répondu avant de voir que Stéphane avait ajouté la solution de ligne de lecture. J'ai supprimé ma réponse, mais ensuite, j'ai supprimé le commentaire lorsque j'ai vu le commentaire demandant des détails sur la solution readline
Alex Stragies
2
J'en ai maintenant ajouté un peu plus dans ma réponse.
Stéphane Chazelas
1
Des réponses ciblées comme la vôtre et des réponses complètes comme celles de Stéphane ont toutes deux leur place. Ayez un vote positif!
évêque
5

Utilisation lesspour afficher le message d'aide

Il peut être utile de voir le contexte environnant des lignes correspondant à votre requête de recherche.

hh () { "${1}" --help | less -p "${2}" ; }

La syntaxe pour appeler cette bashfonction est similaire à la fonction qhdans la réponse de @ tgwtdt, le premier argument étant la commande à examiner et le second argument étant le terme de recherche. Par exemple:

hh ls size
hh ls "symbolic link"

Cela ouvre le message d'aide complet dans less, met en surbrillance chaque instance du terme de recherche et fait défiler jusqu'à la première instance du terme de recherche. Vous pouvez ensuite appuyer sur npour faire défiler vers l'avant jusqu'à la ligne suivante contenant le terme de recherche, à nnouveau pour le suivant, etc. Pour revenir à une instance précédente, appuyez sur N. Utilisez les Home, End, Page Up, Page Down, Up Arrowet les Down Arrowtouches de navigation générale. Appuyez sur qou Qpour quitter lesset revenir à la ligne de commande.

Gaultheria
la source
3

J'ai aimé la solution de @tgwtdt, alors je l'ai un peu améliorée.

Cela fait la même chose, mais fait un peu pour gérer les erreurs et essaie également de traiter les intégrés.

qh utilise () au lieu de {}, donc qh1 () et out sont locaux (en sous-shell).

function qh () (
    function qh1 () {
      out="$(help "$1" 2>&1 )"
      [ $? -ne 0 ] && return 1
      echo "$out"
    }

    type -all "$1" ; { qh1 "$1" || "$1" --help 2>/dev/null || man "$1" 2>/dev/null ;} | egrep -i -- "$2"
) 
Joe
la source