tsch: using foreach on files or directories with spaces in names

deepstructure

Registered
im writing script to check directory sizes against a copy on another drive. unfortunately, it's my itunes music directory, so almost all the directory names have spaces in them.

here's my problem: using the foreach command with a wildcard creates failure.

for instance using foreach to do an action on a list of directories like so:

foreach dir ( * )
du -sk $dir
end

produces something like the following:

123840 AC_DC
16084 ATB
35160 A_Teens
du: Aaron: No such file or directory
du: Neville: No such file or directory
du: &: No such file or directory
du: Robbie: No such file or directory
du: Robertson: No such file or directory

(yes i listen to both ac/dc and a-teens - what of it??)

amending the foreach like so:

foreach dir ( "A* )
du -sk $dir
end

fixes the problem:

123840 AC_DC
16084 ATB
35160 A_Teens
6340 Aaron Neville & Robbie Robertson

all well and good, because the shell is parsing out the value of $dir automatically. the actual value is:

AC_DC ATB A_Teens Aaron Neville & Robbie Robertson (one string)

so of course this breaks down when you want to do anything more. what i want to do is isolate the size variable and use it to compare against the copy of each directory on the other drive - to verify the copy is complete.

so when i try this:

foreach dir ( "A*" )
set presize = `du -sk $dir`
echo $presize
end

this should give me the same list as above, but now with each one in a variable ($presize), which i could then do something like this too and isolate the size value:

set size = `echo $presize | awk '{print $1}'`

but instead it gives me this:

123840 AC_DC 16084 ATB 35160 A_Teens 6340 Aaron Neville & Robbie Robertson

which if i run the above line on simply gives me the first value:

123840

instead of a list of the size data for each directory like this:

123840
16084
35160
6340

how do i get my foreach to treat each directory as an "each" within my script? it works on the command line in the shell, but doesn't work the same way in my script. what am i doing wrong?

any help is appreciated!
 
When you wrap the glob expression in double quotes, it expands to a single string. As a result, you're only executing the body of the loop once, meaning you're executing "du" once, producing the output you're seeing (e.g. "du dir1 dir2 dir3"). Instead, wrap the variable $dir in double quotes like this:

Code:
#!/bin/tcsh
foreach dir ( A* )
    set presize = `du -sk "$dir" | awk '{print $1}'`
    echo $presize
end
 
Back
Top