To nie działa. Czy można to zrobić w znalezieniu? A może muszę xargs?
find -name 'file_*' -follow -type f -exec zcat {} \| agrep -dEOE 'grep' \;
To nie działa. Czy można to zrobić w znalezieniu? A może muszę xargs?
find -name 'file_*' -follow -type f -exec zcat {} \| agrep -dEOE 'grep' \;
Odpowiedzi:
Zadaniem interpretacji symbolu potoku jako instrukcji do uruchomienia wielu procesów i potokowania wyniku jednego procesu do wejścia innego procesu jest odpowiedzialność powłoki (/ bin / sh lub równoważnej).
W twoim przykładzie możesz albo użyć powłoki najwyższego poziomu, aby wykonać potokowanie w następujący sposób:
find -name 'file_*' -follow -type f -exec zcat {} \; | agrep -dEOE 'grep'
Pod względem wydajności wynik ten kosztuje jedno wywołanie find, liczne wywołania Zcat i jedno wywołanie zgody.
Spowodowałoby to odrodzenie tylko jednego procesu uzgadniania, który przetworzyłby wszystkie dane wyjściowe wygenerowane przez liczne wywołania Zcat.
Jeśli z jakiegoś powodu chciałbyś kilkakrotnie wywołać zgodę, możesz:
find . -name 'file_*' -follow -type f \
-printf "zcat %p | agrep -dEOE 'grep'\n" | sh
To konstruuje listę poleceń za pomocą potoków do wykonania, a następnie wysyła je do nowej powłoki w celu ich wykonania. (Pominięcie ostatniego „| sh” to dobry sposób na debugowanie lub wykonywanie suchych uruchomień linii poleceń w ten sposób.)
Pod względem wydajności wynik ten kosztuje jedno wywołanie find, jedno wywołanie sh, liczne wywołania zcat i liczne wywołania zgody.
Najbardziej wydajnym rozwiązaniem pod względem liczby wywołań poleceń jest sugestia Paula Tomblina:
find . -name "file_*" -follow -type f -print0 | xargs -0 zcat | agrep -dEOE 'grep'
... która kosztuje jedno wywołanie znaleziska, jedno wywołanie xargs, kilka wywołań Zcat i jedno wywołanie zgody.
-exec sh -c "… | … " \;
.
rozwiązanie jest proste: uruchom przez sh
... -exec sh -c "zcat {} | agrep -dEOE 'grep' " \;
-c
opcji. W przeciwnym razie pojawi się zagadkowy No such file or directory
komunikat o błędzie.
find -type f -name '*.mdds' -exec sh -c "echo {} | sed -e 's/_[0-9]\+//g' | xargs mv {}" \;
find . -name "file_*" -follow -type f -print0 | xargs -0 zcat | agrep -dEOE 'grep'
Możesz także wykonać potok do while
pętli, która może wykonywać wiele akcji na find
zlokalizowanym pliku . Więc tutaj jest jeden do przeszukiwania jar
archiwów dla danego pliku klasy Java w folderze z dużą dystrybucją jar
plików
find /usr/lib/eclipse/plugins -type f -name \*.jar | while read jar; do echo $jar; jar tf $jar | fgrep IObservableList ; done
kluczową kwestią jest to, że while
pętla zawiera wiele poleceń odnoszących się do przekazanej nazwy pliku oddzielonych średnikiem, a te polecenia mogą zawierać potoki. W tym przykładzie odbijam nazwę pasującego pliku, a następnie wymieniam zawartość filtrowania archiwum dla danej nazwy klasy. Dane wyjściowe wyglądają następująco:
/usr/lib/eclipse/plugins/org.eclipse.core.contenttype.source_3.4.1.R35x_v20090826-0451.jar /usr/lib/eclipse/plugins/org.eclipse.core.databinding.observable_1.2.0.M20090902-0800 .jar org / eclipse / core / databinding / observable / list / IObservableList .class /usr/lib/eclipse/plugins/org.eclipse.search.source_3.5.1.r351_v20090708-0800.jar / usr / lib / eclipse / plugins / org.eclipse.jdt.apt.core.source_3.3.202.R35x_v20091130-2300.jar /usr/lib/eclipse/plugins/org.eclipse.cvs.source_1.0.400.v201002111343.jar / usr / lib / eclipse / plugins / org.eclipse.help.appserver_3.1.400.v20090429_1800.jar
w mojej powłoce bash (xubuntu10.04 / xfce) naprawdę sprawia, że dopasowana nazwa klasy jest pogrubiona, ponieważ fgrep
podświetla dopasowany ciąg; dzięki temu bardzo łatwo jest zeskanować listę setek jar
plików, które zostały przeszukane i łatwo zobaczyć wszelkie dopasowania.
w systemie Windows możesz zrobić to samo z:
for /R %j in (*.jar) do @echo %j & @jar tf %j | findstr IObservableList
zwróć uwagę, że w systemie Windows separatorem poleceń jest „&” not ”; i że „@” tłumi echo polecenia, aby uzyskać uporządkowane wyjście, tak jak w przypadku linux find powyżej; chociaż findstr
nie powoduje pogrubienia dopasowanego łańcucha, więc musisz przyjrzeć się bliżej wynikowi, aby zobaczyć nazwę pasującej klasy. Okazuje się, że polecenie „for” systemu Windows zna kilka sztuczek, takich jak przechodzenie między plikami tekstowymi ...
cieszyć się
Przekonałem się, że uruchomienie polecenia powłoki łańcuchowej (sh -c) działa najlepiej, na przykład:
find -name 'file_*' -follow -type f -exec bash -c "zcat \"{}\" | agrep -dEOE 'grep'" \;
Jeśli szukasz prostej alternatywy, możesz to zrobić za pomocą pętli:
for i in $(find -name 'file_*' -follow -type f);do zcat $i | agrep -dEOE 'grep');done
lub bardziej ogólna i łatwa do zrozumienia forma:
for i in $(YOUR_FIND_COMMAND);do YOUR_EXEC_COMMAND_AND_PIPES );done
i zamień {} na $ i w YOUR_EXEC_COMMAND_AND_PIPES