01-24-07 06:16 PM
Hi all,
I need to process files in a loop, and I am having problems with filename
spaces, big time.
Everything is in bash 3.1.
The script in question is supposed to build a link-forest: replicate a direc
tory
structure, but replace each file with a link pointing to the original. I dec
ided
to do gro of the work with a recursive function:
function make_links
{
for each_item in $LIST; do
if [ -L "$1/$each_item" ]; then
# link
rm -f "$each_item" # mercilessly overwrite existing stuff
ln -s `readlink "$1/$each_item"` "$each_item"
elif [ -d "$1/$each_item" ]; then
# directory
mkdir -p "$each_item"
cd "$each_item"
make_links "$1/$each_item" &
cd ..
else
# file
rm -f "$each_item" # mercilessly overwrite existing stuff
ln -s "$1/$each_item" "$each_item"
fi
done
return 0
}
I am having significant issues with spaces in filenames, and I figure everyt
hing
revolves around the way I generate the $LIST in the above function.
My first attempt was to _replace_ the $LIST with `ls -1A $1`. I wanted this
to
handle dot-files as well. Unfortunately, any file with a space would be hand
led
as two items. No good!
Second attempt was to double quote the "`ls -1A $1`", which generates ONE hu
ge
argument to the for loop. Again, no good!
In the next round I experimented with `ls -mA $1`. This generates a comma
separated list, but it also brings several new problems. To break up the com
ma
separated list, I used IFS=','. However, this left each_item with a leading
extra space. I corrected this with a each_item=`eval echo $each_item` inside
the
loop. Unfortunately, the list also generates a newline every 80 characters (
or
sooner) in the $LIST, so once in a while I was left with each_item being set
to
something like "\nfilename". At the first occurrence of $each_item in the
function I would get something like <filename> not found. 'man ls' hinted th
at
the secret is in the variable COLUMNS. Seems export COLUMNS=0 does nothing.
Right now I got COLUMNS=65000, but what if I have a directory that is longer
?
This seems like the best option out of the ones I tried. However, what if I
have
a directory with more than 65000 characters worth? Or, what is a better way
of
getting rid of the newlines?
I also tried to use expansion. I generated the list with simple $1/*, which
also
gives me the complete path, and no dot-files. The path can be corrected with
each_item=`basename "$each_item"`. However, trying to fix the dot-files with
adding $1/.* to the list, has "very interesting" effects -> DO NOT TRY THIS
AT
HOME! After having to reboot the machine and purge the disk of a _lot_ of li
nks,
the sys.admin. warned me against doing any more stupid things.
Anyone has any other _workable_ solution?
TIA, SK.
--
It may be that your sole purpose in life
is simply to serve as a warning to others.
-----
Candy for spammers:
http://members.shaw.ca/grubb/spamthis.html
[ Post a follow-up to this message ]
|