BASH SHELL: How to list contents of a directory that contains sub dirs that have a spaces in the sub-dir name and these sub dirs then contain a sub dir with a special character for a name

lolaferrari used Ask the Experts™
I have a directory that contains sub-directories where the sub directory names all contain spaces and each further sub dir contains a sub dir with that is actually called @. How do you pass that as a variable in a script. I'd like to do it this way    for dir in ls /opt/app; do ls /opt/app/'${dir}'/'@'; done but this doesn't work and not sure what to do to get it to work.

                App Dir 1 App Dir 2 App Dir 3 App Dir 4 AppDir 5
                            @          @         @              @              @

On the command line if I want to list the contents of these dirs I have put single quotes around the Sub Dir Name in order to escape the special character since the name contains spaces but this is such a poor way to do it because I don't want to have to list the sub dirs by name but do it more the way i tried above.
ls /opt/app/'App Dir 1'/'@'/ ; ls /opt/app/'App Dir 2'/'@' ; ls /opt/app/'App Dir 3'/'@' ; ......

I'd like to do it this way
for dir in ls /opt/app; do ls /opt/app/'${dir}'/'@'; done  but not sure who to get this way to work
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
David FavorFractional CTO
Distinguished Expert 2018

Depends on what you're doing with the output.

One of these simple commands will suffice...

ls -R
find . -type f

Open in new window

Then apply grep to filter as required.

Sometimes it's just easier to do a find + grep than deal with odd characters.
Distinguished Expert 2017
-type f is a match for  regular file
-type d is a directory
find path -type d -name  '* *' -depth 2

I based on what you are looking for would use perl to iterate through ....
Try this:

for i in opt/app/*/@ ; do ls "$i" ; done

Open in new window

nociSoftware Engineer
Distinguished Expert 2018
How about:

find /opt/apps -type f -print0 | xargs -0 ls -l 

Open in new window

The -print0 on find and the -0 on xargs work in tandem. -print0 sees to it that each file & path name is terminated with a nul-character ('\0')
xargs -0 accepts nul-terminated strings and handles each as an argument to the program mentioned after it....
xargs also collects as much names as could fit in the commandline to call the next command with a lot of single arguments.

another way can be:
find /opt/apps -type f -print0 | xargs -n 1 -0 command-that-can-handle-only-one-file-name

Open in new window

Here some differences are shown:
find /opt/apps -type f -print0 | xargs -n 1 -0 echo      # only one arg per command
find /opt/apps -type f -print0 | xargs -n 2 -0 echo      # 2 files / command
find /opt/apps -type f -print0 | xargs -n 5 -0 echo      # 5 files per command

Open in new window


Thanks very much for all your input. all of it was helpful

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial