web-dev-qa-db-ja.com

bashを使用して、ディレクトリ内のすべてのファイルからクラスパスを作成するにはどうすればよいですか?

これはreally bash guruの簡単な無料サービスです:

質問

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-codeは、次のようなものです。

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

simple bashスクリプトでこれを実現する方法とは何ですか?

61
gMale

新しい回答
(2012年10月)

クラスパスリストを手動で作成する必要はありません。 Javaは、jarファイルを含むディレクトリの便利なワイルドカード構文をサポートします。

Java -cp "$LIB/*"

*inside引用符であることに注意してください。)

man Javaからの説明:

特別な便宜のため、*のベース名を含むクラスパス要素は、拡張子が.jarまたは.JAR(Javaのディレクトリ内のすべてのファイルのリストを指定することと同等と見なされます_プログラムは、2つの呼び出しの違いを判別できません)。

たとえば、ディレクトリfooにa.jarおよびb.JARが含まれている場合、jarファイルの順序が指定されていないことを除き、クラスパス要素foo/*A.jar:b.JARに展開されます。指定されたディレクトリ内のすべてのjarファイルは、隠しファイルも含め、リストに含まれます。 *のみで構成されるクラスパスエントリは、現在のディレクトリ内のすべてのjarファイルのリストに展開されます。 CLASSPATH環境変数(定義されている場合)も同様に展開されます。クラスパスのワイルドカード拡張は、Java仮想マシンが起動する前に発生します。Javaプログラムは、環境を照会することを除いて、拡張されていないワイルドカードを認識しません。


旧回答

良い

シンプルだが完璧ではないソリューション:

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

スペースを含むファイル名を正しく処理できないというわずかな欠陥があります。それが問題になる場合は、もう少し複雑なバージョンを試してください。

より良い

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

これは、findコマンドが-printfをサポートしている場合にのみ機能します(GNU findがサポートします)。

Mac OS XのようにGNU findがない場合は、代わりにxargsを使用できます。

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

ベスト?

別の(より奇妙な)方法は、フィールド区切り変数$IFSを変更することです。これは非常に奇妙に見えますが、すべてのファイル名でうまく動作し、Shellビルトインのみを使用します。

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

説明:

  1. JARSはファイル名の配列に設定されます。
  2. IFS:に変更されます。
  3. 配列がエコーされ、$IFSが配列エントリ間の区切り文字として使用されます。ファイル名の意味は、コロンで区切られて出力されます。

これらはすべてサブシェルで実行されるため、$IFSへの変更は永続的ではありません(これはbaaaadになります)。

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

別のバリエーションがあります:

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

printf -vsprintfに似ています。ブレースを展開すると、余分なコロンが末尾から削除されます。

2

最高の

すべてawk =の方が良い

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