使用bash,如何在目录中的所有文件中创建一个类路径? [英] Using bash, how do you make a classpath out of all files in a directory?

查看:188
本文介绍了使用bash,如何在目录中的所有文件中创建一个类路径?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这将是一个 简单免费的bash大师:

This will be a really simple freebie for a bash guru:

问题

使用bash,您如何在目录中的所有文件中创建一个类路径?

Using bash, how do you make a classpath out of all files in a directory?

详细信息

给定一个目录:

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

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

that contains nothing but *.jar files such as:

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

我需要以以下形式创建一个冒号分隔的类路径变量:

I need to create a colon-separated classpath variable in the form:

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

几乎表达我正在寻找的逻辑的一些seudo代码将符合以下条件:

Some seudo-code that nearly expresses the logic I'm looking for would be along the lines of:

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

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

What is a simple way to accomplish this via bash script?

推荐答案

新答案

(October 2012)

没有必要手动构建类路径列表。 Java支持对包含jar文件的目录的方便的通配符语法。

There's no need to manually build the classpath list. Java supports a convenient wildcard syntax for directories containing jar files.

java -cp "$LIB/*"

(请注意, c >

man java 中的说明:


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

As a special convenience, a class path element containing a basename of * is considered equivalent to specifying a list of all the files in the directory with the extension .jar or .JAR (a java program cannot tell the difference between the two invocations).

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

For example, if directory foo contains a.jar and b.JAR, then the class path element foo/* is expanded to a A.jar:b.JAR, except that the order of jar files is unspecified. All jar files in the specified directory, even hidden ones, are included in the list. A classpath entry consisting simply of * expands to a list of all the jar files in the current directory. The CLASSPATH environment variable, where defined, will be similarly expanded. Any classpath wildcard expansion occurs before the Java virtual machine is started — no Java program will ever see unexpanded wildcards except by querying the environment.






旧答案

简单而不完美的解决方案:

Simple but not perfect solution:

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

有一个小小的缺陷,这不会正确处理文件名。如果这个事情尝试这个稍微复杂一点的版本:

There's a slight flaw in that this will not handle file names with spaces correctly. If that matters try this slightly more complicated version:

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

只有您的find命令支持 -printf (如GNU find do)。

This only works if your find command supports -printf (as GNU find does).

如果您没有GNU 查找,就像在Mac OS X上一样可以使用 xargs

If you don't have GNU find, as on Mac OS X, you can use xargs instead:

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



/ h3>

另一种(weirder)的方法是更改​​字段分隔符变量 $ IFS 。这是非常奇怪的,但是对所有文件名的表现都很好,只能使用shell内置。

Best?

Another (weirder) way to do it is to change the field separator variable $IFS. This is very strange-looking but will behave well with all file names and uses only shell built-ins.

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

说明:


  1. JARS 设置为数组的文件名。

  2. IFS 更改为

  3. 数组被回显, $ IFS 用作数组条目之间的分隔符。意思是文件名以它们之间的冒号打印。

  1. JARS is set to an array of file names.
  2. IFS is changed to :.
  3. The array is echoed, and $IFS is used as the separator between array entries. Meaning the file names are printed with colons between them.

所有这些都在子shell中完成,所以更改为 $ IFS 不是永久的(这将是baaaad)。

All of this is done in a sub-shell so the change to $IFS isn't permanent (which would be baaaad).

这篇关于使用bash,如何在目录中的所有文件中创建一个类路径?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆