简体   繁体   中英

Problem using “find” in shell scripting

I while back I wrote a shell script that automatically runs a python script over any c++ files it can find in a specified directory. I tested it, it worked fine, and I saved it and forgot about it; problem is I've came back to use it and encountered a problem (turns out I didnt test it enough eh?).

Anyway, the source directory paths I was testing before had no spaces in their names, eg

/somedirectory/subfolder/src/

But when I try and run the script using a path with spaces in it, eg

/Documents\ and\ Settings/subfolder/src/

It doesnt work.

I've located where the problem is, but I'm not sure how to fix it. Here's the code causing the problem:

names=( $(find "${SOURCE_ROOT_DIRECTORY}" -regex "[A-Za-z0-9]*.*\(cpp\|h\|cc\)$"))

The regular expression works with paths with no spaces, so I'm not sure if there's a problem with the regular expression, or if the "find" command stops when it encounters a space.

Can anyone help?

find doesn't "stop" when it hits files with spaces in their names. The problem occurs when try to store them as elements in an array.

Change IFS to the newline character (by default it is space):

#change IFS
OLDIFS=$IFS
IFS=$'\n' 

#run find
names=($(find . -regex "[A-Za-z0-9]*.*\(cpp\|h\|cc\)$"))

#restore IFS
IFS=$OLDIFS

#test out the array
echo "size: ${#names[@]}"
for i in "${names[@]}"
do
   echo "$i"
done

The canonical usage pattern is:

find subfolder/ -type f -name '*.cpp' -print0 |
     xargs -0rn1 myscript.py

This has all the bells and whistles, you can probably do without -type f and perhaps some of the xargs flags

you can use read

while read -r file; do
    names+=("$file")
done < <(find "${SOURCE_ROOT_DIRECTORY}" -regex "[A-Za-z0-9]*.*\(cpp\|h\|cc\)$")

a small test

$ mkdir -p /tmp/test && cd $_
$ touch foo bar "ab cd"
$ ls
ab cd  bar  foo
$ while read -r file; do names+=("$file"); done < <(find /tmp/test -type f); 
$ echo ${#names[@]}
3
$ for file in "${names[@]}"; do echo "$file"; done;
/tmp/test/ab cd
/tmp/test/bar
/tmp/test/foo
$ unset names file

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM