TL;DR: Use a find-based loop
The other day I was wondering how to execute a command in each sub-directory of a project.
In python, you have os.walk. In C, I would've probably written myself something just for fun etc. In shell, I know you have find
which is capable of finding all directories (find (dir) -type d
). All I need to do is to wrap this in a loop and for this one has two options:
-
Commmand line style
find (dir) -type d | xargs ...
or
find (dir) -type d -exec(dir) COMMAND
-
Script style with a loop
while IFS= read -r d; do ... done << (find . -type d)
The choice between the two depends of the complexity of the command you want to execute inside.
Scripted approach
My use case was to execute a mvn clean
in each directory ( the root dir is the container of all my maven-based development projects). Therefore, my logic would look something along the lines:
if (we have a pom in the directory)
# execute mvn clean
else
# do not do anything
The result is:
#!/usr/bin/env bash
ORIGINAL_PWD=`pwd`
cd "$1"
CWD=`pwd`
cleanlog="CWD/clean.log"
date > $cleanlog
SIZE_START=`du -hcs .`
while IFS= read -r d; do
if [[ $d != *".git/"* ]]; then
if [ -f "$d/pom.xml" ]; then
echo "Cleaning [$d]..."
cd "$d"
mvn clean >> $cleanlog 2>&1
cd "$CWD"
fi
fi
done < <(find . -type d)
SIZE_END=`du -hcs .`
echo "Start: ${SIZE_START}"
echo "End : ${SIZE_END}"
cd "${ORIGINAL_PWD}"
Notes:
if [[ $d != *".git/"* ]];
istrue
if the found directory doesn't contain the string".git/"
in it.if [ -f "$d/pom.xml" ];
istrue
if the directory has a pom.xml file.- The script also shows the directory size before and after executing the loop.
HTH,
Member discussion: