You need to realize that the command that you are running, viz.,
for dir in `find . -maxdepth 1 -type d | grep -v \\.$ | awk -F'./' '{print $2}'`
there are 2 levels of quote interpretation. In the first level, that is at the level of the command line where from the command is issued, the text under the backquotes `....` is first scanned for backslashes and $variables, just as in a double quotes interpolation. Since that $ is sitting lonesome at the end, so it won't be expanded. There's no harm in escaping it though.
So this shall leave that grep -v \\.$ ----> grep -v \.$
Now after this step is over, it shall be handed over to a subshell for running. And in that subshell the command grep -v \.$ is parsed and the backslash is taken away so what grep executable gets at the end of this phase is: grep -v .$
Now all the nonempty lines will match this pattern and find generated all nonempty lines, for the simple reason that filenames mustn't be nonempty.
So that means all find's output are gonna be selected and hence the inverse of that implies that no output from find shall be selected. So awk is all dressed up but has really nowhere to go.
Solution:
There are many things you can take up to fix the issue.
- Add one more backslash to the grep, making it :
grep -v \\\.$
Based on what happens in each step of quote expansion for this scenario, convince yourself that this fix works.
- Use the $() form of command interpolation as in this format the quoting begins anew withing the $() unlike the `` form of backquoting.
- Use single quotes in the grep, making it:
grep -v '\.$'
- Use character classes to escape the . :
grep -v '[.]$'
- Do everything in
find command itself:
find . -maxdepth 1 -type d ! -name . -exec sh -c '
for d do printf "dir: %s\n" "${d:2}"; done
' sh {} +