0
for n in `cd src; find . -name "*.java"; cd -`;
  do a=`echo $n | cut -d '.' -f2`;
  if [[ src/$a.java -nt build/$a.class ]];
    then echo src/$a.java;
  fi;
done

它列出了 src 树中的所有 java 文件;然后对于每一个,它都会删除后缀“.java”(cut -d '.' -f2因为find .输出以 为前缀.)。然后它-nt用于测试 src 树中的 java 文件是否比构建树中相应的类文件更新;如果它较新,则输出。[javac 然后可以使用它来仅编译所需的 src 文件,而不是使用antor make]

问题是它太慢了,大约需要 275ms。如何让它更快?

或者有没有更快的方法在 bash 中做到这一点?我看不到如何使用find, diff, rsyncnor make(它似乎不会自动遍历树,并且需要明确列出的源文件)。

4

4 回答 4

1

尝试这个:

for f in src/*.java; do 
  file=`basename $f`; 
  if [[ src/$file -nt build/${file//.java/} ]]; then 
     echo src/$file; 
  fi; 
done 
于 2009-12-04T11:39:33.550 回答
1

我不知道这种结构是否会更快,但可能值得一试:

while read n
do
     # capture the basename all at once
     [[ $n =~ src/(.*)\.java ]]   # escape the parentheses for Bash < 3.2 (or thereabouts)
     [[ $n -nt "build/${BASH_REMATCH[1]}.class" ]] && echo $n
done < <(find src -name "*.java")

while表格可能不会提供任何提升。倒塌的if可能。正则表达式可能会提供很小的贡献。

正如您所发现的,消除呼叫cut产生了最大的不同。

于 2009-12-04T13:54:28.103 回答
0

采用kon的文件名修改方法,速度平均从320ms提高到45ms。谢谢康!

for n in `cd src; find . -name "*.java"; cd -`; do
  if [[ src/$n -nt build/${n/.java/.class} ]];
     then echo src/$n;
  fi;
done

原来的现在有点慢(275ms;现在是 320ms);我不知道为什么。我正在使用同一条线路。播放视频后可能会出现不同的系统源。

编辑重新开始的评论:修改“src/”而不是cd src;...。cd -;请注意,两者$n$n2使用了 [您不能嵌套 ${var/A/B} 构造,可以吗?]

for n in `find src -name "*.java"`; do
  n2=${n/src/}
  if [[ $n -nt build/${n2/.java/.class} ]];
     then echo $n;
  fi;
done
于 2009-12-04T12:24:39.220 回答
0

ant 执行智能构建逻辑,除非源被修改,否则它不会构建类。

您可能还想研究 scons,它不是原生 Java 构建工具,但在编译高效复杂的构建树时非常方便,并且也有 java builder。

于 2009-12-04T12:47:40.920 回答