LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Newbie (https://www.linuxquestions.org/questions/linux-newbie-8/)
-   -   bash script question (https://www.linuxquestions.org/questions/linux-newbie-8/bash-script-question-477448/)

edward_scott 08-25-2006 10:09 PM

bash script question
 
hi,

sorry if this is in the wrong place, I was having trouble figuring out where the appropriate forum for this post is.

I am toying around with bash scripts. all I am trying to do at the moment is write a script that sucesfully iterates through every file in a given directory. for now I am just echo-ing the files to the command line. I know there is no need for a bash script to do this, but I am just trying to make sure the loop does what I want it to.

which it doesn't. if the files in the directory have spaces in them, they get output on separate lines. worse yet, if the input directroy has spaces in its path, it tries to find files as if they were separate directories.

for instance:
Quote:

shakermaker@localhost ~ $ ls test
four.txt one two.txt three.txt
shakermaker@localhost ~ $ scripts/iterate.x test
test
four.txt
one\
two.txt
three.txt
Quote:

shakermaker@localhost ~ $ scripts/iterate.x /media/torrents/2\ Many\ DJ\'s/
/media/torrents/2 Many DJ's/
ls: /media/torrents/2: No such file or directory
ls: Many: No such file or directory
ls: DJ's/: No such file or directory
my script is as follows:

Code:

#!/bin/bash
#iterates through a directory, printing each file to the console

MIN_ARGS=1
E_OPTERROR=65

if [ $# -lt $MIN_ARGS ]
then
    echo "Usage: `basename $0` path"
    exit $E_OPTERROR
fi

FILEPATH=$1
echo $FILEPATH

for i in `ls -b $FILEPATH`;
do
    echo $i
done

any help?

sdexp 08-25-2006 11:15 PM

It seems that your problem deals with having spaces in filenames.

The solution to this is simply an extra step which I have come to think of and use over the past some years.

Put simply, you could output your statements (literally: echo "echo \"$filename\"" >> temp_file) and have that output to a temporary file. This temporary file should look like:
Code:

echo "file1.txt"
echo "file with space.txt"
echo "file3.txt"

Now have this temporary file output and executed by bash:
Code:

cat temp_file | bash
This takes care of spaces, by treating each line as an entity rather than each word. This is yet another reason to not have spaces in filenames. I only use the aforementioned technique for my music, which must have spaces.

spirit receiver 08-26-2006 02:59 AM

The return value of ls is split at whitespace to form a list of separate values, and the loop will iterate over the values. One solution is to use "ls -1" instead, which will print a single filename on each line, and tell Bash to consider the newline character as the only field sepearator. You can do this by specifying "IFS=$'\n'" before the loop. But note that setting IFS might sometimes have unwanted effects in other situations.
Another option would be to pipe the output of "ls -1" into a loop like
Code:

while read; do echo "$REPLY"; done
Furthermore, for a similar reason, you should use
Code:

echo "$i"
to print the filenames, as an argument with whitespace will be considered as a list of separate arguments otherwise.

edward_scott 08-26-2006 01:52 PM

thanks so much! this helps a lot, I used your suggestions to succesfully work around the issues I mentioned earlier.

now I'm having a problem with filenames that have appostrophes in them. ls -b doesn't escape them apparently. how do people generally deal with spaces and special characters in filenames? there must be a common way of working around this, because I would imagine it is a common problem.

I really need to just fix my filenames (curse you windows! teaching such bad habits), but that doesn't solve the problem, it just prevents it from occurring. a good script will deal with any possible file name.

spirit receiver 08-26-2006 02:54 PM

I'd suggest not to use the -b switch at all, but to use double quotes around the filename wherever it appears. Then you should be fine.


All times are GMT -5. The time now is 08:25 AM.