Como posso editar todos os arquivos retornados pelo find no vi no Linux?


27

Algo que eu me vejo fazendo muito é executar um comando find e depois editar todos eles no vi, que se parece com isso:

> find . "*.txt"
./file1.txt
./file2.txt
./path/to/file3.txt

> vi ./file1.txt ./file2.txt ./path/to/file3.txt

Existe uma maneira inteligente e simples de fazer isso tudo em uma linha de comando?


1
Você pode inseri-lo no vi: find. "* .txt" | xargs vi
MaQleod 15/09/11

1
@ MaQleod: Tecnicamente, seria canalizar para xargs .
grawity


Tubulação para xargsdestruir o meu terminal. A solução é adequada a uma infra @DevSolar
typelogic

Respostas:


41

Isso deve fazer o truque:

find . -name "*.txt" -exec vim {} + 

Use o Vim, é melhor para sua saúde. :-)

A +opção muitas vezes esquecida -execfaz com que todos os nomes de arquivos (até o limite de comprimento da linha) apareçam em uma linha, ou seja, você ainda abre todos os arquivos em uma vim sessão (navegado com o arquivo :nseguinte e o :Narquivo anterior).

Com vim -pvocê obtém uma guia de arquivo para cada arquivo. Verifique :help tab-page-commandspara mais detalhes.

Com vim -ovocê obterá janelas divididas horizontalmente para cada arquivo, vim -Ojanelas verticalmente divididas. Verifique :help window-move-cursorpara mais detalhes.

Observe que a versão anterior desta resposta vim $(find . -name "*.txt"),, não funciona com espaços nos nomes de arquivos e tem implicações de segurança.

A tubulação no xargs vidá um Warning: Input is not from a terminalterminal mais um comportamento completamente falso posteriormente. O grawity do usuário explicou o motivo em um comentário abaixo e com um pouco mais de explicação nesta pergunta .


4
Não sei o quanto você sabe sobre o vim, mas levei / para sempre / para descobrir que: n mostra o próximo arquivo e: N mostra o arquivo anterior.
zpletan 15/09/11

4
@DevSolar: O Vim espera que seu stdin seja igual ao seu terminal de controle e executa vários ioctls relacionados ao terminal no stdin diretamente. (Você pode considerar isso um bug. O Vim certamente pode abrir /dev/ttye chamar ioctl (); é muito preguiçoso fazê-lo.) Quando invocado pelo xargs, o vim recebe /dev/nullcomo entrada padrão, o que simplesmente ignora os ioctls de controle do terminal.
grawity

3
@ zpletan: vim -pse você quiser guias de arquivo. ( gtE gTpara navegar, ou clique com o mouse.)
grawity

2
Para sua informação, para evitar o aviso ao enviar uma mensagem vim, basta especificar -como o primeiro argumento, como em echo foobar | vim -.
21411 Konrad Rudolph

2
@ Konrad Rudolph: find . -name "*.txt" | vim -dá-lhe uma sessão vim em um arquivo sem nome que contém os nomes dos arquivos encontrados, o que não é o que o OP pediu ...
DevSolar


1

Além disso, se você deseja que eles sejam abertos um de cada vez, também é possível usar find -exec ou um loop for simples. Editado pelo comentário de ceving.

find . -name "*.txt" -exec vi {} \;

ou

OLDIFS=$IFS
IFS=$(echo -en "\n\b")
for i in `find . -name "*.txt"`
    do
        vi $i
    done
IFS=$OLDIFS

...Mas porque você iria querer fazer aquilo?
DevSolar 15/09/11

@DevSolar O primeiro é apontar a capacidade de localização, o segundo é um loop de uso geral. Talvez você queira fazer algo em cada arquivo antes de editá-lo.
OldWolf 15/09

Você já tentou o segundo? Primeiro: a descoberta retorna o diretório atual porque -nameestá ausente. E segundo: o comando falha miseravelmente assim que um nome de arquivo contém um espaço. -1 para resposta imprudente.
ceving 16/09/11

Na verdade, o assunto de espaços nos nomes de arquivos também se aplica à minha resposta. Não consigo nem pensar em uma maneira de lidar com eles adequadamente sem transformá-lo de uma linha de comando em um pequeno script próprio. Há uma boa razão pela qual os espaços nos nomes de arquivos são desencorajados.
DevSolar 16/09

@ceving Um ponto válido. Eu presumi que os pôsteres originais achavam que era válido para as necessidades dele. Edição.
OldWolf 16/09

0

Se você já digitou seu findcomando, acho que pode ser muito mais fácil usar xargspara abrir os resultados da pesquisa:

find . -name "*.txt" | xargs vim -p

A -popção diz ao vim para abrir cada arquivo em uma nova guia. Acho isso mais conveniente do que apenas usar buffers, mas se você não o fizer, deixe essa opção.


obrigado Conectei-o para localizar, então meu comando foi: localizar nome do arquivo | xargs vim -p
talsibony 13/09/16

0

Para editar tudo *.txt, você pode simplesmente executar: vim *.txt. Para editar arquivos retornados por find, leia mais.


No Unix / macOS, você pode usar findcom o BSD xargs(consulte :) man xargs, por exemplo

find -L . -name "*.txt" -type f -print0 | xargs -o -0 vim

-o( xargs): Reabra stdin como / dev / tty no processo filho antes de executar o comando.

Relacionado: O terminal funcionou após a chamada do Vim com xargs no Vim.SE.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.