Bash排除点划线前缀

时间:2011-06-30 10:57:25

标签: bash

似乎无法解决这个问题。

我有一个bash脚本来搜索文件夹并排除某些文件类型。

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

我想要排除以dot-dash开头的文件._但上面只是拒绝工作。

这是一些更多的脚本,但我仍然使用._

开头复制文件

O / S是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

1 个答案:

答案 0 :(得分:2)

首先 - 不要这样做。

files="`find ...`"

在空格上拆分名称,这意味着Some File成为两个文件,SomeFile。即使拆分换行也是不安全的,因为有效的UNIX文件名可以包含$'\n'(除/以外的任何字符,并且null在UNIX文件名中有效)。代替...

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)

以上做了很多事情:

  • 对包含空格或换行符的文件名是安全的。
  • 它使用cmp -q,而不是diff。在进行更改时,cmp会立即退出,而不是需要计算两个文件之间的增量,因此速度更快。

阅读BashFAQ #1UsingFindBashPitfalls #1,了解这与原版之间的一些差异。

另外 - 我已经验证这正确排除了以._开头的文件名 - 但原始版本也是如此。您真正想要的可能是排除与*._*而不是._*匹配的文件名?