Jak mogę edytować wszystkie pliki zwrócone przez find in vi w systemie Linux?

27

Coś, co często robię, polega na uruchomieniu polecenia find, a następnie edycji ich wszystkich w vi, co wygląda mniej więcej tak:

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

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

Czy istnieje sprytny i prosty sposób na zrobienie tego wszystkiego w jednym wierszu poleceń?

abeger
źródło
1
Możesz potokować go do vi: find. „* .txt” | xargs vi
MaQleod,
1
@MaQleod: Technicznie rzecz biorąc, byłoby to przesyłanie strumieniowe do xargs .
grawity
Rurociągi, które xargszniszczyły mój terminal. Właściwym rozwiązaniem jest poniższe rozwiązanie @DevSolar
typelogic

Odpowiedzi:

41

To powinno załatwić sprawę:

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

Użyj Vima, lepiej dla twojego zdrowia. :-)

Często pomijana +opcja -execpowoduje, że wszystkie nazwy plików (do limitów długości linii) pojawiają się w jednym wierszu, tzn. Nadal wszystkie pliki są otwierane w jednej vim sesji (nawigacja :nza pomocą następnego i :Npoprzedniego pliku).

Otrzymasz vim -pzakładkę pliku dla każdego pliku. Sprawdź :help tab-page-commandswięcej szczegółów.

Dzięki vim -otemu otrzymasz okna podzielone w poziomie dla każdego pliku, vim -Ookna podzielone w pionie. Sprawdź :help window-move-cursorwięcej szczegółów.

Pamiętaj, że poprzednia wersja tej odpowiedzi vim $(find . -name "*.txt")nie działa ze spacjami w nazwach plików i ma wpływ na bezpieczeństwo.

Pipingowanie xargs vidaje Warning: Input is not from a terminalpotem plus terminal z całkowicie fałszywym zachowaniem. Użytkownik grawitacji wyjaśnił dlaczego w komentarzu poniżej i nieco więcej wyjaśnień w tym pytaniu .

DevSolar
źródło
4
Nie wiem, ile wiesz o vimie, ale zajęło mi / na zawsze / odkrycie, że: n pokazuje następny plik, a: N pokazuje poprzedni.
zpletan
4
@DevSolar: Vim spodziewa się, że stdin będzie taki sam jak terminal kontrolny, i bezpośrednio wykonuje różne związane z nim ioctl. (Można uznać to za błąd. Vim z pewnością może otworzyć /dev/ttyi wywołać ioctl (); jest to po prostu zbyt leniwe, aby to zrobić.) Gdy jest wywoływany przez xargs, vim otrzymuje /dev/nulljako standardowe wejście, co po prostu ignoruje ioctls sterujące terminalem.
grawity
3
@zpletan: vim -pjeśli chcesz zakładki plików. ( gti gTnawigować lub klikać myszą).
grawity
2
Do Twojej wiadomości, aby uniknąć ostrzeżenia podczas instalacji vim, po prostu podaj -jako pierwszy argument, jak w echo foobar | vim -.
Konrad Rudolph,
2
@Konrad Rudolph: find . -name "*.txt" | vim -daje ci sesję vima na nienazwanym pliku zawierającym nazwy znalezionych plików, co nie jest tym, o co poprosił OP ...
DevSolar 16.09.11
4

Lub uruchom vima i stamtąd:

:args **/*.txt
Benoit
źródło
1

Dodatkowo, jeśli chcesz, aby były otwierane pojedynczo, możesz także użyć find -exec lub prostej pętli for. Edytowane według komentarza Cevinga.

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

lub

OLDIFS=$IFS
IFS=$(echo -en "\n\b")
for i in `find . -name "*.txt"`
    do
        vi $i
    done
IFS=$OLDIFS
OldWolf
źródło
... ale dlaczego chcesz to zrobić?
DevSolar
@DevSolar Pierwszy polega na wskazaniu możliwości znajdowania, drugi to pętla ogólnego przeznaczenia. Być może chcesz coś zrobić dla każdego pliku przed jego edycją.
OldWolf,
Czy próbowałeś kiedyś drugiego? Po pierwsze: find zwraca bieżący katalog, ponieważ go -namebrakuje. Po drugie: polecenie kończy się niepowodzeniem, gdy tylko nazwa pliku zawiera spację. -1 za niewłaściwą odpowiedź.
Ceving
Właściwie temat spacji w nazwach plików dotyczy również mojej odpowiedzi. Nie mogę nawet wymyślić sposobu, aby odpowiednio sobie z nimi poradzić, nie zmieniając go z wiersza poleceń w mały własny skrypt. Jest dobry powód, dla którego spacje w nazwach plików są odradzane.
DevSolar,
@ceving Ważny punkt. Przypuszczałem, że oryginalne plakaty okazały się ważne dla jego potrzeb. Redagowanie.
OldWolf,
0

Jeśli już wpisałeś findpolecenie, uważam, że xargsotwarcie wyników wyszukiwania może być znacznie łatwiejsze :

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

Ta -popcja każe vimowi otworzyć każdy plik w nowej karcie. Uważam, że jest to wygodniejsze niż używanie buforów, ale jeśli tego nie zrobisz, po prostu zrezygnuj z tej opcji.

Cory Klein
źródło
dziękuję, podłączyłem go, aby zlokalizować, więc moje polecenie brzmiało: zlokalizuj nazwę pliku | xargs vim -p
talsibony,
0

Aby edytować wszystko *.txt, wystarczy uruchomić: vim *.txt. Aby edytować pliki zwrócone przez find, czytaj dalej.


W systemach Unix / macOS można używać findz BSD xargs(patrz :) man xargs, np

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

-o( xargs): Ponownie otwórz stdin jako / dev / tty w procesie potomnym przed wykonaniem polecenia.

Powiązane: Terminal przestał działać po wywołaniu Vima za pomocą xargs na Vim.SE.

kenorb
źródło