Comment `localiser 'plusieurs fichiers et les ouvrir dans vim?

10

Supposons que j'ai un fichier nommé filename123.txtet que c'est le fichier unique qui est nommé ainsi, et je peux le locatefaire avec la commande locate filename123. Et il ne renvoie que ce fichier.

Maintenant, je veux l'ouvrir avec vi/ vim. Mais je ne veux pas aller à cet emplacement et taper la vicommande suivie du nom de fichier. Ici, je veux que le résultat de locate filename123soit ajouté à la commande vi. Comment faire? J'ai déjà essayé:

locate filename123 | vi

Mais cela ne fonctionne pas. Et cette erreur vient dans le terminal:

santosh@santosh:~$ locate filename123 | vi
Vim: Warning: Input is not from a terminal
Vim: Error reading input, exiting...
Vim: Finished.
Santosh Kumar
la source

Réponses:

12

Vous pouvez utiliser xargs:

locate filename123 | xargs vi

Par défaut, xargsil exécutera le moins possible d'instances de la commande spécifiée, en transmettant autant de paramètres que possible en fonction de l' ARG_MAX du système . Pour limiter le nombre de paramètres transmis à une instance de vi, utilisez xargsl' -noption ' .

Pour gérer les noms de fichiers contenant des espaces, utilisez xargsl' -doption ' :

locate filename123 | xargs -d '\n' vi

Pour gérer les noms de fichiers contenant des sauts de ligne, utilisez xargsl' -0option locate' avec l' -0option':

locate -0 filename123 | xargs -0 vi

(Si -0n'est disponible sur aucun d'entre eux, vérifiez --nullaussi, ou une autre façon de spécifier le caractère \000comme délimiteur.)

homme au travail
la source
Pouvez-vous me dire ce qui m'empêchait avant d'ouvrir ce fichier?
Santosh Kumar
1
@Santosh Vous passiez la sortie de la locatecommande en entrée à vi. Vi, comme tout autre programme, s'attend à ce que le nom du ou des fichiers fonctionne comme arguments.
Gilles 'SO- arrête d'être méchant'
@manatwork Le problème est que je ne peux pas localiser et ouvrir le nom de fichier avec des espaces dedans. Par exemple, cette commande ouvrira plusieurs fichiers dans vim: localisez I \ have \ to \ download | xargs vi
Santosh Kumar
3

Vous pouvez utiliser l'extension de commande:

vi "$(locate filename123 | head -n1)"

Pour faire vimlire son stdin, vous pouvez le faire vim -, mais cela vous donnera juste la sortie locatedont les chemins sont des noms de fichiers. Cela pourrait cependant fonctionner, l'utilisation de vim gfla commande normale ouvrira alors le chemin sur lequel se trouve le curseur.

Éditer

Dans le cas de noms de fichiers contenant des espaces, il vaut mieux utiliser l' xargsoption mentionnée ou la vimsolution décrite ci-dessus. Remarque pour gftravailler, vous devez ajouter de l'espace à isfname:

set isfname+=32

Cette astuce et ses alternatives sont décrites ici .

Modifier 2

Ajout de citations et headcomme suggéré par PeterO dans les commentaires .

Thor
la source
Pour les fichiers contenant des espaces, lorsque j'insère \ dans le nom de fichier, comme vi $ (recherchez un autre fichier \). Le vim l'ouvre comme deux fichiers distincts, anotheret file:(.
Santosh Kumar
Votre réponse ne fonctionne que lorsque je n'ai pas d'espace dans le fichier que je recherche.
Santosh Kumar
Réponse mise à jour.
Thor
2
@Thor: Pour un seul fichier, comme mentionné dans la question, il vous suffit de mettre des guillemets autour de la substitution de processus: vi "$(locate filename123)"... Pour vous assurer qu'il n'a qu'un seul nom de fichier à traiter:vi "$(locate filename123 |head -n1)"
Peter.O
PeterO: Vous avez raison, je n'ai testé qu'avec plusieurs hits. J'ai ajouté vos commentaires à la réponse.
Thor
1

Le moyen le plus simple est de passer locateen substitution de shell , comme:

vim $(locate filename123)

Vous pouvez également envisager d'utiliser findau lieu de locatepasser des noms de fichiers à modifier, par exemple:

find . -name 'filename123' -exec vim {} +

Sur Unix / OSX, vous pouvez utiliser xargsun -oparamètre, comme:

locate filename123 | xargs -o vim

-oRouvrez stdin en tant que / dev / tty dans le processus enfant avant d'exécuter la commande. Ceci est utile si vous souhaitez que xargs exécute une application interactive.

Ou sous Linux, essayez la solution de contournement suivante en utilisant:

locate filename123 | xargs -J% sh -c 'vim < /dev/tty $@'

Si vous utilisez différentes commandes, utilisez la substitution de commandes pour y parvenir, comme:

vim $(locate filename123)
vim `locate filename123`

Vous pouvez également utiliser GNU parallelau lieu de xargspour forcer l'allocation tty, par exemple:

locate filename123 | parallel -X --tty vi

Remarque: parallelsous Unix / OSX ne fonctionnera pas car il a des paramètres différents et ne prend pas en charge tty.

De nombreuses autres commandes populaires fournissent également une allocation pseudo-tty (comme -tdansssh ), alors vérifiez l'aide.

Une autre suggestion serait d'utiliser vipe(un canal de commande Vim) ou d'utiliser le script simple suivant:

#!/bin/sh
# usage: locate filename123 | vip
exec vim < /dev/tty "$@"

En relation:

Kenorb
la source