filenames with spaces and list in a for loop
- From: SiKing <nospam@xxxxxxxxxxxxx>
- Date: Wed, 24 Jan 2007 15:30:20 +0000
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 directory structure, but replace each file with a link pointing to the original. I decided 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 everything 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 handled as two items. No good!
Second attempt was to double quote the "`ls -1A $1`", which generates ONE huge 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 comma 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 that 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 links, 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
.
- Follow-Ups:
- Re: filenames with spaces and list in a for loop
- From: Bill Marcum
- Re: filenames with spaces and list in a for loop
- From: Eric Moors
- Re: filenames with spaces and list in a for loop
- Prev by Date: Re: Move a file content into a varibale
- Next by Date: for patsy: very creative nntp server - idpa ojse ogri - (1/1)
- Previous by thread: /bin/cat <<-EOM 1>&2
- Next by thread: Re: filenames with spaces and list in a for loop
- Index(es):
Relevant Pages
|