Wykonaj akcję w każdym podkatalogu używając Bash
Pracuję nad skryptem, który musi wykonać akcję w każdym podkatalogu określonego folderu.
Jaki jest najskuteczniejszy sposób na napisanie tego?
9 answers
for D in `find . -type d`
do
//Do whatever you need with D
done
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-01-07 16:41:19
Wersja, która unika tworzenia pod-procesu:
for D in *; do
if [ -d "${D}" ]; then
echo "${D}" # your processing here
fi
done
Lub, jeśli akcja jest pojedynczym poleceniem, jest to bardziej zwięzłe:
for D in *; do [ -d "${D}" ] && my_command; done
Lub jeszcze bardziej zwięzła wersja (dzięki @ enzotib ). Zauważ, że w tej wersji każda wartość D
będzie miała końcowy ukośnik:
for D in */; do my_command; done
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:18:20
Najprostszym nie rekurencyjnym sposobem jest:
for d in */; do
echo "$d"
done
/
na końcu mówi, używać tylko katalogów.
Nie ma potrzeby
- znajdź
- awk
- ...
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-11-14 08:35:37
Użyj polecenia find
.
W GNU find
możesz użyć parametru -execdir
:
find . -type d -execdir realpath "{}" ';'
Lub używając parametru -exec
:
find . -type d -exec sh -c 'cd -P "$0" && pwd -P' {} \;
Lub z xargs
poleceniem:
find . -type d -print0 | xargs -0 -L1 sh -c 'cd "$0" && pwd && echo Do stuff'
Lub używając dla pętli:
for d in */; { echo "$d"; }
dla rekurencyjności spróbuj zamiast tego rozszerzonego globbingu (**/
) (enable by: shopt -s extglob
).
Aby uzyskać więcej przykładów, zobacz: Jak przejść do każdego katalogu i wykonać polecenie? W SO
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 10:31:33
Handy one-liners
for D in *; do echo "$D"; done
for D in *; do find "$D" -type d; done ### Option A
find * -type d ### Option B
Opcja A jest prawidłowa dla folderów ze spacjami pomiędzy. Ponadto, ogólnie szybciej, ponieważ nie drukuje każdego słowa w nazwie folderu jako osobnego elementu.
# Option A
$ time for D in ./big_dir/*; do find "$D" -type d > /dev/null; done
real 0m0.327s
user 0m0.084s
sys 0m0.236s
# Option B
$ time for D in `find ./big_dir/* -type d`; do echo "$D" > /dev/null; done
real 0m0.787s
user 0m0.484s
sys 0m0.308s
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-10-12 20:58:00
find . -type d -print0 | xargs -0 -n 1 my_command
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-10-22 20:18:21
Spowoduje to utworzenie subshell (co oznacza, że wartości zmiennych zostaną utracone po zakończeniu pętli while
):
find . -type d | while read -r dir
do
something
done
To nie będzie:
while read -r dir
do
something
done < <(find . -type d)
Każda z nich będzie działać, jeśli w nazwach katalogów są spacje.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-10-23 00:26:21
Możesz spróbować:
#!/bin/bash
### $1 == the first args to this script
### usage: script.sh /path/to/dir/
for f in `find . -maxdepth 1 -mindepth 1 -type d`; do
cd "$f"
<your job here>
done
Lub podobne...
Wyjaśnienie:
find . -maxdepth 1 -mindepth 1 -type d
:
Znajdź tylko katalogi o maksymalnej głębokości rekurencyjnej 1 (tylko podkatalogi $1) i minimalnej głębokości 1 (nie obejmuje bieżącego folderu .
)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-07-25 06:26:00
Akceptowana odpowiedź będzie łamana na białych spacjach, jeśli nazwy katalogów je zawierają, A preferowaną składnią jest $()
dla bash / ksh. Użycie GNU find
-exec
opcja z +;
eg
find .... -exec mycommand +;
#this is same as passing to xargs
Lub użyj pętli while
find .... | while read -r D
do
...
done
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-10-22 23:24:11