使用bash,你如何在目录中的所有文件中创build一个类path?

这将是一个非常简单的免费赠送bash大师:

使用bash,你如何在目录中的所有文件中创build一个类path?


细节

给定一个目录:

LIB=/path/to/project/dir/lib 

只包含* .jar文件,例如:

 junit-4.8.1.jar jurt-3.2.1.jar log4j-1.2.16.jar mockito-all-1.8.5.jar 

我需要创build一个冒号分隔的类pathvariables的forms:

 CLASSPATH=/path/to/project/dir/lib/junit-4.8.1.jar:/path/to/project/dir/lib/jurt-3.2.1.jar:/path/to/project/dir/lib/log4j-1.2.16.jar:/path/to/project/dir/lib/mockito-all-1.8.5.jar 

几乎expression我所寻找的逻辑的一些seudo-code将会是:

 for( each file in directory ) { classpath = classpath + ":" + LIB + file.name } 

什么是通过bash脚本完成这个简单的方法?

新的答案
(2012年10月)

没有必要手动构build类path列表。 Java为包含jar文件的目录支持一种便捷的通配符语法。

 java -cp "$LIB/*" 

(请注意, * 引号 )。

man java解释:

作为一个特别的方便,包含*的基类名称的类path元素被认为等价于指定扩展名为.jar.JAR (java程序无法区分两个调用之间的区别)的目录中的所有文件的列表。

例如,如果目录foo包含a.jarb.JAR ,那么类path元素foo/*将扩展为A.jar:b.JAR ,不同之处在于未指定jar文件的顺序。 列表中包含指定目录中的所有jar文件,甚至隐藏的文件。 一个由*组成的类path条目将展开为当前目录中所有jar文件的列表。 定义的CLASSPATH环境variables将被类似地扩展。 任何类path通配符扩展都会在Java虚拟机启动之前发生 – 除查询环境之外,Java程序不会看到未扩展的通配符。


老答案

简单但不完美的解决scheme:

 CLASSPATH=$(echo "$LIB"/*.jar | tr ' ' ':') 

有一个轻微的缺陷,这将不能正确处理文件名与空格。 如果这件事情尝试这个稍微复杂的版本:

更好

 CLASSPATH=$(find "$LIB" -name '*.jar' -printf '%p:' | sed 's/:$//') 

这只适用于如果你的find命令支持-printf (就像GNU find一样)。

如果你没有find GNU,就像在Mac OS X上一样,你可以使用xargs代替:

 CLASSPATH=$(find "." -name '*.jar' | xargs echo | tr ' ' ':') 

最好?

另一种(weirder)方法是更改​​字段分隔符variables$IFS 。 这看起来很奇怪,但是对于所有文件名都会performance得很好,而且只使用shell内build。

 CLASSPATH=$(JARS=("$LIB"/*.jar); IFS=:; echo "${JARS[*]}") 

说明:

  1. JARS被设置为一个文件名的数组。
  2. IFS更改为:
  3. 该数组被回显, $IFS被用作数组条目之间的分隔符。 意思是文件名之间用冒号打印。

所有这些都是在一个子shell中完成的,所以对$IFS的修改并不是永久的(这可能会成为baaaad)。

 for i in $LIB/*.jar; do CLASSPATH=$CLASSPATH:$i done CLASSPATH=`echo $CLASSPATH | cut -c2-` 

这是另一个变化:

 printf -v CLASSPATH "$LIB/%s:" *.jar; CLASSPATH=${CLASSPATH%:} 

printf -v有点像sprintf 。 括号扩展从最后删除额外的冒号。

BESTEST

awk = 一切都好

 CLASSPATH=$(awk '$0=lib"/"FILENAME' ORS=":" lib=$LIB *.jar)