Ouvrir un fichier donné par le résultat d'une commande dans vim

34

Je me retrouve à faire ce qui suit presque tous les jours

  1. Lancer une recherche ( find -name somefile.txt)
  2. Ouvrir le résultat dans vim

Le problème est que je dois copier et coller le résultat de finddans la vimcommande. Y a-t-il un moyen d'éviter d'avoir à faire cela? J'ai expérimenté un peu ( find -name somefile.txt | vim) mais n'ai rien trouvé qui fonctionne.

Merci d'avance

smauel
la source

Réponses:

31

Vous pouvez utiliser la substitution de commande:

vim $(find -name somefile.txt)

ou

find -name somefile.txt -exec vim {} \;
dogbane
la source
1
D'accord. Si c'est ce dont vous avez besoin, recherchez -name somefile.txt | xargs vim
balki
3
Non, cela ne fonctionne pas correctement et peut même endommager votre terminal! Vous ne pouvez pas accéder à xargs vim, car vim s'attend à ce que les entrées proviennent d'un terminal interactif.
Dogbane
1
Un utilisateur anonyme note que cela échouera si le nom du fichier a des espaces
Michael Mrozek
4
Une autre alternative serait vim `find -name somefile.txt`. @StuartPowers Alternativement, vous pouvez utiliser vim `!-1`si vous avez déjà utilisé cette recherche était votre commande précédente
Bernhard
1
@balki pour utiliser xargs dans ce scénario, vous devez utiliser l'indicateur -o, c'est dans man: -o Rouvrez stdin en tant que / dev / tty dans le processus enfant avant d'exécuter la commande. Ceci est utile si vous voulez que xargs exécute une application interactive.
Davidmh
7

Essaye ça:

  1. commencer vim
  2. dans vim, utilisez ce qui suit:

:r!find /<path> -name 'expression'

Les résultats devraient apparaître dans vim une fois la recherche terminée.

Ou

Essayer:

find /<path> -name > results.txt
vim results.txt 
Karl
la source
Ma solution fait exactement la même chose, mais pourquoi est-elle votée?
balki
5

Si cela ne vous dérange pas de réexécuter la commande: appuyez sur Upet ajoutez une xargscommande. Ou utilisez la substitution d'historique et exécutez

!! | xargs vim          # won't work with file names containing \'" or whitespace
!! | xargs -d \\n vim   # GNU only (Linux, Cygwin)

Il existe un moyen léger d’enregistrer la sortie d’une commande qui fonctionne en ksh et zsh mais pas en bash (il faut que le côté sortie d’un pipeline soit exécuté dans le shell parent). Tuyau de la commande dans la fonction K(définition zsh ci - dessous), qui k EEP sa sortie dans la variable $K.

function K {
    K=("${(@f)$(tee /dev/fd/3)}") 3>&1;
}
find  |K
vim $K

L'enregistrement automatique de la sortie de chaque commande n'est pas vraiment possible avec le shell seul; vous devez exécuter la commande dans un terminal émulé. Vous pouvez le faire en exécutant à l'intérieur script(un utilitaire BSD, mais disponible sur la plupart des ordinateurs, y compris Linux et Solaris), qui enregistre toutes les sorties de votre session dans un fichier (il faut encore un peu d'effort pour détecter de manière fiable la dernière invite dans le script ).

Gilles, arrête de faire le mal
la source
2

J'aime utiliser les ticks arrières `(c'est sur la même touche que le ~)

> vim `find . -name somefile.txt`

Les ticks arrière exécutent la commande à l'intérieur des ticks et la sortie peut alors être utilisée par la commande. Ce qui précède trouvera tous les fichiers somefile.txt, vous permettant ainsi de vous :nextdéplacer dans tous les fichiers.

C'est très utile si vous passez quelques essais à affiner la commande, car vous pouvez alors utiliser la substitution d'historique pour répéter la commande pour l'éditeur.

> find . -name somefile.txt
./debug/somefile.txt
./somefile.txt
> vi `!!`
Martin York
la source
2

Je dois avoir manqué le point ici, parce que je voudrais utiliser:

:find **/somefile.txt

(si je savais qu'il n'y en avait qu'un :echo &path ) ou si je les voulais tous:

:args **/somefile.txt

Edit: Whoa! Ok, donc j'ai bien manqué le point - vous voulez que la liste de recherche, pas les fichiers réels soient ouverts? Essayez (encore une fois dans Vim):

!!find . -name somefile.txt

-- ma faute :)

Barry Arthur
la source
1

Comme @davidmh l'a souligné dans les commentaires, vous pouvez utiliser xargsl'indicateur -osi vous souhaitez utiliser une application interactive.

find . -name somefile.txt | xargs -o vim

Si vous ne l'utilisez pas -o, vous allez probablement gâcher l'état du terminal après avoir quitté vim. Si vous l'avez fait, vous devriez pouvoir réinitialiser votre terminal avec la commande suivante:

reset
durum
la source
0

J'ai écrit une fonction pvimqui fait ce que tu veux. Si plusieurs lignes sont acheminées vers ce dernier, pvimil ignore tout sauf le premier. Il pourrait être étendu pour ouvrir plusieurs fichiers dans vim.

stu@sente ~ $ function pvim() { read -r somefile; exec < /dev/fd/1; vim "$somefile"; }
stu@sente ~ $ type pvim
pvim is a function
pvim ()
{
    read -r somefile;
    exec < /dev/fd/1;
    vi "$somefile"
}

Utilisez-le comme:

stu@sente ~ $ find . -name "foo.txt" | pvim

qui chargera le premier "foo.txt" dans vim comme si vous aviez tapé:

vim $(find . -name "foo.txt | head -n1")

sente
la source
0

Voici une xargssolution plus simple que celles déjà mentionnées:

find -name somefile.txt | xargs vim -p

L' -poption indique vimd'ouvrir chaque fichier dans un onglet séparé. Je trouve cela plus pratique que d'utiliser des tampons.

Cory Klein
la source
0

J'ai trouvé que l'ouverture d'un fichier à l'aide de locate in vim est extrêmement pratique et beaucoup plus rapide que find.

La commande suivante recherche un fichier appelé app.pydans le chemin contenant le répertoire MyPythonProject.

:args `locate '*MyPythonProject*app.py'`
Searene
la source