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

编程入门 行业动态 更新时间:2024-10-22 23:23:55
使用bash,如何在目录中的所有文件中创建一个类路径?(Using bash, how do you make a classpath out of all files in a directory?)

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

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


细节

给定一个目录:

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

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

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代码将符合以下条件:

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

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

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

Question

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


Details

Given a directory:

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

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

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 }

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

最满意答案

新答案 (2012年10月)

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

java -cp "$LIB/*"

(注意*是引号内。)

人的解释man java :

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

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


老回答

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

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

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

更好

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

这仅在您的find命令支持-printf (如GNU find ))时才起作用。

如果您没有GNU find ,如Mac OS X,您可以使用xargs :

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

最好?

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

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

说明:

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

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

New Answer (October 2012)

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

java -cp "$LIB/*"

(Notice that the * is inside the quotes.)

Explanation from man 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).

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.


Old Answer

Good

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:

Better

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

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

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

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

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[*]}")

Explanation:

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

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

更多推荐

本文发布于:2023-08-05 06:12:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1430222.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:创建一个   路径   文件   如何在   目录中

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!