开发者

Bash Exclude dot-dash prefixes

Can't seem to crack this one.

I have a bash script to search a folder and exclude certain file types.

list=`find . -type f ! \( -name "*data.php" -o -name "*.log" -o -iname ".开发者_StackOverflow_*" -o -path "*patch" \)`

I want to exclude files which start with dot-dash ._ but the above just refuses to work.

Here's some more of the script, but I am still getting files copied with start with ._

O/S is CentOS 5.3

    list=`find . -type f ! \( -name "*data.php" -o -name "*.log" -o -iname "._*" -o -path "*patch" \)`
    for a in $list; do
       if [ ! -f "$OLDFOL$a" ]; then
            cp --preserve=all --parents $a $UPGFOL
          continue
       fi
       diff $a "$OLDFOL$a" > /dev/null
       if [[ "$?" == "1" ]]; then
            # exists & different so copy
            cp --preserve=all --parents $a $UPGFOL
       fi
    done


First -- don't do it that way.

files="`find ...`"

splits names on whitespace, meaning that Some File becomes two files, Some and File. Even splitting on newlines is unsafe, as valid UNIX filenames can contain $'\n' (any character other than / and null is valid in a UNIX filename). Instead...

getfiles() {
  find . -type f '!' '(' \
    -name '*data.php' -o \
    -name '*.log' -o \
    -iname "._*" -o \
    -path "*patch" ')' \
    -print0
}
while IFS= read -r -d '' file; do
  if [[ ! -e $orig_dir/$file ]] ; then
     cp --preserve=all --parents "$file" "$dest_dir"
     continue
  fi
  if ! cmp -q "$file" "$orig_dir/$file" ; then
     cp --preserve=all --parents "$file" "$dest_dir"
  fi
done < <(getfiles)

The above does a number of things right:

  • It is safe against filenames containing spaces or newlines.
  • It uses cmp -q, not diff. cmp exits immediately when a change is made, rather than needing to calculate the delta between two files, and is thus far faster.

Read BashFAQ #1, UsingFind, and BashPitfalls #1 to understand some of the differences between this and the original.

Also -- I've validated that this correctly excludes filenames which start with ._ -- but the original version did too. Perhaps what you really want is to exclude filenames matching *._* rather than ._*?

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜