/ / znajdź foldery i cd do nich - bash, shell, find

znajdź w nich foldery i cd - bash, shell, find

Chciałem napisać krótki skrypt o następującej strukturze:

 find the right folders
cd into them
replace an item

Więc moim problemem jest to, że dostaję odpowiednie foldery findale nie wiem, jak wykonać akcję dla każdej linii finddaje mi. Próbowałem tego z pętlą for taką jak ta:

for item in $(find command)
do magic for item
done

ale problem polega na tym, że to polecenie wypisze względne nazwy ścieżek, a jeśli w mojej ścieżce jest miejsce, rozdzieli ścieżkę w tym punkcie.

Mam nadzieję, że zrozumiałeś mój problem i możesz dać mi wskazówkę.

Odpowiedzi:

2 dla odpowiedzi № 1

Możesz uruchamiać polecenia z opcją -exec znajdowania bezpośrednio:

find . -name some_name -exec your_command {} ;

1 dla odpowiedzi nr 2

Jednym ze sposobów jest:

find command -print0 |
while IFS= read -r -d "" item ; do
... "$item" ...
done

-print0 i read ... -d "" spowoduje, że znak NUL zostanie użyty do oddzielenia ścieżek i upewnij się, że kod działa dla wszystkich ścieżek, w tym ścieżek zawierających spacje i znaki nowej linii. Oprawa IFS opróżnić i użyć -r opcja do read zapobiega modyfikowaniu ścieżek przez read.

Zauważ, że while pętla działa w podpowłoce, więc zmienne ustawione w niej nie będą widoczne po zakończeniu pętli. Jeśli jest to problem, jednym ze sposobów rozwiązania tego problemu jest użycie podstawiania procesów zamiast potoku:

while IFS= ...
...
done < <(find command -print0)

Inną opcją, jeśli masz Bash 4.2 lub nowszy, jest użycie lastpipe opcja (shopt -s lastpipe) aby uruchomić ostatnie polecenie w potokach w bieżącej powłoce.


0 dla odpowiedzi № 3

Jeśli wzór, który chcesz znaleźć, jest wystarczająco prosty i masz bash 4, możesz nie potrzebować find. W takim przypadku możesz użyć globstar zamiast tego dla rekurencyjnego globowania:

#!/bin/bash

shopt -s globstar
for directory in **/*pattern*/; do
(
cd "$directory"
do stuff
)
done

W nawiasach każda operacja odbywa się w podpowłoce. Może to mieć koszt wydajności, ale zwykle nie i oznacza, że ​​nie musisz pamiętać cd za każdym razem z powrotem.

Gdyby globstar nie jest opcją (bo twoja find instrukcje nie są prostym wzorcem ani dlatego, że nie masz powłoki, która je obsługuje), której możesz użyć find w podobny sposób:

find . -whatever -exec bash -c "cd "$1" && do stuff" _ {} ;

Możesz użyć + zamiast ; przekazywać wiele argumentów za każdym razem, ale wykonując jeden katalog na powłokę (co jest ; zrobi) ma podobne korzyści i koszty do używania powyższego wyrażenia podpowłoki.