Como `localizar` vários arquivos e abri-los no vim?

10

Suponha que eu tenho um arquivo chamado filename123.txte é o único arquivo que é chamado assim, e eu posso locatelo com o comando locate filename123. E ele retorna apenas esse arquivo.

Agora eu quero abri-lo com vi/ vim. Mas não quero ir para esse local e digite o vicomando seguido pelo nome do arquivo. Aqui eu quero que o resultado locate filename123seja anexado ao comando vi. Como posso fazer isso? Eu já tentei:

locate filename123 | vi

Mas isso não funciona. E este erro vem no terminal:

santosh@santosh:~$ locate filename123 | vi
Vim: Warning: Input is not from a terminal
Vim: Error reading input, exiting...
Vim: Finished.
Santosh Kumar
fonte
possível duplicata de xargs e vi - "Input não é de um terminal"
kenorb

Respostas:

12

Você pode usar xargs:

locate filename123 | xargs vi

Por padrão xargs, executará o menor número possível de instâncias do comando especificado, passando o maior número possível de parâmetros, de acordo com o ARG_MAX do sistema . Para limitar o número de parâmetros passados ​​para uma instância de vi, use xargs' -noption.

Para manipular nomes de arquivos contendo espaços, use xargsa -dopção ' :

locate filename123 | xargs -d '\n' vi

Para lidar com nomes de arquivos contendo novas linhas, use xargsa -0opção ' juntamente com locatea -0opção ' s :

locate -0 filename123 | xargs -0 vi

(Se -0não estiver disponível em nenhum deles, verifique --nulltambém, ou outra maneira de especificar o caractere \000como delimitador.)

homem a trabalhar
fonte
Você pode me dizer o que estava me impedindo antes de abrir este arquivo?
Santosh Kumar
1
@Santosh Você estava passando a saída do locatecomando como entrada para o vi. O Vi, como qualquer outro programa, espera que o nome do (s) arquivo (s) funcione como argumento.
Gilles 'SO- stop be evil'
@manatwork O problema é que não consigo localizar e abrir o nome do arquivo com espaços. Por exemplo, este comando abrirá vários arquivos no vim: localize I \ have \ to \ download | xargs vi
Santosh Kumar
3

Você pode usar a expansão de comando:

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

Para fazer a vimleitura do stdin, você pode fazer vim -, mas isso fornecerá apenas a saída dos locatecaminhos do nome do arquivo. Isso pode funcionar, porém, o uso vim gfdo comando normal abrirá o caminho em que o cursor está.

Editar

No caso de nomes de arquivos com espaços, é melhor usar a xargsopção mencionada ou a vimsolução descrita acima. Nota para fazer o gftrabalho, você precisa adicionar espaço para isfname:

set isfname+=32

Esta dica e alternativas são descritas aqui .

Editar 2

Citações adicionadas e headconforme sugerido por PeterO nos comentários .

Thor
fonte
Para arquivos com espaços em branco, quando insiro \ no nome do arquivo, como vi $ (localize outro \ arquivo). O vim o abre como dois arquivos separados anothere file:(.
Santosh Kumar
Sua resposta só funciona quando não tenho espaços no arquivo que estou localizando.
Santosh Kumar
Resposta atualizada.
Thor
2
@ Thor: Para um único arquivo, como mencionado na pergunta, você só precisa colocar aspas na substituição do processo: vi "$(locate filename123)"... Para garantir que ele tenha apenas um nome de arquivo para lidar:vi "$(locate filename123 |head -n1)"
Peter.O
PeterO: Você está certo, eu só testei com vários hits. Adicionei seus comentários à resposta.
Thor
1

A maneira mais simples é passar locatecomo substituição de shell , como:

vim $(locate filename123)

Você também pode considerar usar em findvez de locatepassar nomes de arquivos para editar, por exemplo:

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

No Unix / OSX você pode usar xargscom o -oparâmetro, como:

locate filename123 | xargs -o vim

-oReabra stdin como / dev / tty no processo filho antes de executar o comando. Isso é útil se você deseja que o xargs execute um aplicativo interativo.

Ou no Linux, tente a seguinte solução alternativa usando:

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

Se você estiver usando comandos diferentes, use a substituição de comandos para conseguir isso, como:

vim $(locate filename123)
vim `locate filename123`

Como alternativa, use o GNU em parallelvez de xargsforçar a alocação de tty, no exemplo:

locate filename123 | parallel -X --tty vi

Nota: parallelno Unix / OSX não funcionará, pois possui parâmetros diferentes e não suporta tty.

Muitos outros comandos populares também fornecem alocação pseudo-tty (como -tem ssh), portanto, procure ajuda.

Outra sugestão seria usar vipe(um canal de comando do Vim) ou usar o seguinte script simples:

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

Palavras-chave:

kenorb
fonte