Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

Under a directory called a there are many subfolders where I want to do something. The same for all. I do the following but it applies only to the first subdirectory:

for i in "a/*"
    do
            #echo $i
            cd $i
            mkdir test
            mv *_no test
            touch aaa
            cd ..
    done

The above code I want to be executed in every directory under a.

share|improve this question
add comment

3 Answers 3

up vote 2 down vote accepted

When using globs, you should remove the quotes. If not, the globs is not expanded.

So :

for i in a/*
share|improve this answer
add comment

The first cd chdirs into the first directory (two levels of subdirs). And after that you can't cd into the second because you've only gone back one level so you're not back where you started from. But even then, you're looping over one single value: "a/*".

Since you've put quotes around that, it is not getting expanded.

However you've forgotten to put quotes around $i, so it does get expanded at that point as arguments to cd.

There are a lot of other problems with your code.

Some suggestions of improvements:

for i in a/*/; do
  (
    cd -- "$i" &&
      mkdir -p test || exit
    mv -- *_no test
    touch aaa
  )
done
share|improve this answer
2  
Just to fill out the explanation a bit: the (...) construct sch uses here creates a subshell that localizes some actions, such as changing shell variables (not used here) and changing the current directory (used here). So when the subshell is finished, you're left at the same top-level directory you were in when you started the subshell. That's why cd ../.. isn't needed. –  dubiousjim Oct 19 '12 at 14:49
add comment

Quoting $i inside the loop doesn't do anything since a/*/ is already expanded into words. For example if a/*/ expands to a/My Documents/, in the first loop $i = a/My and second loop $i = Documents/ Try

find . -maxdepth 1 -type d | while read i; do
  (
    cd -- "$i" &&
      mkdir -p test || exit
    mv -- *_no test
    touch aaa
  )
done
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.