Jak użyć polecenia „find -exec” do wykonania polecenia w katalogu znalezionego pliku (nie w bieżącym katalogu)?

15

Powiedzmy, że jestem w katalogu, który ma kilka podkatalogów, dir1, dir2, i dir3. Każdy z tych katalogów ma plik fooi chciałbym wykonać to samo polecenie foow każdym z katalogów i zlecić wykonanie tego polecenia z tego katalogu.

Gdybym miał to zrobić „ręcznie”, wyglądałoby to tak:

cd dir1
(execute on foo)
cd ../dir2
(execute on foo)
cd ../dir3
(execute on foo)

Konieczne jest wykonanie polecenia z każdego katalogu . foojest skryptem planowania wsadowego (dla HTCondor, jeśli chcesz wiedzieć) i musi zostać wykonany z każdego podkatalogu, aby wyniki uruchomień uruchomione przez skrypty planowania znalazły się w każdym podkatalogu.

Pytanie „ Znajdź plik i wykonaj polecenie w katalogu pliku ”, o ile wiem, nie odpowiada na moje pytanie. Pierwsza odpowiedź na to pytanie jest raczej obejściem, które nie zadziała w moim przypadku, a druga odpowiedź nie zawiera wystarczającego wyjaśnienia, aby wiedzieć, jak z niej korzystać.

Gwiazda neutronowa
źródło
@roaima, proszę wyjaśnić, jak to jest duplikat. Pierwsza odpowiedź na to pytanie nie pomaga mi, jest bardziej do obejrzenia, a druga odpowiedź nie ma dla mnie żadnego sensu. Potrzebuję więcej wyjaśnień, aby wiedzieć, jak go używać.
NeutronStar

Odpowiedzi:

23

Zakładając, że findobsługuje, użyj -execdiropcji zamiast-exec

find * -name 'foo' -execdir pwd \;

Jeśli nie, proszę podać szczegółowe informacje na temat swojej platformy i / lub dystrybucji (odpowiednio).

roaima
źródło
Kiedy zaczniesz naciskać „znajdź: ścieżka względna” ./nod_modules/.bin ”jest zawarta w zmiennej środowiskowej PATH,„: askubuntu.com/questions/621132/…
Ciro Santilli 冠状 病毒 审查 六四 事件 法轮功
Przepraszam, że mogę tak to napisać, ale -execdir (na Ubuntu) to gówno, ponieważ nie daje {}, ale rodzic {}.
uav
1
@ uav bez znajomości twojego przypadku użycia Nie mogę ci pomóc. Jednak w odpowiedzi na twoje zachcianki dokumentacja wyraźnie stwierdza „ Lubię -exec, ale określone polecenie jest uruchamiane z podkatalogu zawierającego dopasowany plik ”.
roaima
Tak, prawda, jest to szczególny przypadek, jeśli szukasz opcji -type d (= katalog), a następnie nie jest optymalna.
uav
Bez znajomości twojego przypadku użycia nie mogę ci pomóc.
roaima
4

Zakładając, że wiesz dokładnie, w których katalogach chcesz uruchomić swoje polecenie,

for dir in dir1 dir2 dir3; do
    ( cd "$dir" && somecommand foo )
done

lub, zapętlając foopliki,

for foo in */foo; do
  ( cd "${foo%/*}" && somecommand foo )
done

Podkładka zapobiega cdwpływaniu na katalog roboczy reszty skryptu. W ${foo%/*}rozwinięciu podstawiania parametrów do nazwy katalogu, w którym fooplik mieszka (usuwając wszystko po ostatniej /wartości $foo).

Używając standardu, findaby zrobić to samo (w przypadku, gdy foopliki mogą znajdować się głęboko w strukturze katalogów):

find . -type f -name foo -exec sh -c '
    for foo do
        ( cd "${foo%/*}" && somecommand foo )
    done' sh {} +

Innymi słowy: znajdź wszystkie zwykłe pliki o nazwie „foo” w dowolnym miejscu w bieżącym katalogu lub poniżej i podaj nazwy ścieżek do tego skryptu powłoki partiami. Skrypt powłoki powinien iterować po podanych nazwach ścieżek, zmienić katalog na część katalogową każdej nazwy ścieżki, a jeśli to się powiedzie, wykonać somecommand foo.

Aby uzyskać rozwiązanie wykorzystujące niestandardowe -execdir, zobacz odpowiedź roaima . Jego odpowiedź dostosowała się do mojego przykładu:

find . -type f -name foo -execdir somecommand foo ';'
Kusalananda
źródło