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 find
ale nie wiem, jak wykonać akcję dla każdej linii find
daje 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 № 1Moż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.