连接 bash-script 中的路径列表,以冒号作为分隔符

Concatenate list of paths in bash-script, with colon as separator

我有以下由单个命令组成的难以阅读的脚本:

#!/bin/sh

/Library/Java/JavaVirtualMachines/jdk1.8.0_45.jdk/Contents/Home/bin/java \
-classpath /Users/afarber/src/jetty-newbie/EmbeddedWebsocket/target/classes:/Users/afarber/.m2/repository/org/eclipse/jetty/jetty-server/9.3.9.v20160517/jetty-server-9.3.9.v20160517.jar:/Users/afarber/.m2/repository/javax/servlet/javax.servlet-api/3.1.0/javax.servlet-api-3.1.0.jar:/Users/afarber/.m2/repository/org/eclipse/jetty/jetty-http/9.3.9.v20160517/jetty-http-9.3.9.v20160517.jar:/Users/afarber/.m2/repository/org/eclipse/jetty/jetty-util/9.3.9.v20160517/jetty-util-9.3.9.v20160517.jar:/Users/afarber/.m2/repository/org/eclipse/jetty/jetty-io/9.3.9.v20160517/jetty-io-9.3.9.v20160517.jar:/Users/afarber/.m2/repository/org/eclipse/jetty/jetty-servlet/9.3.9.v20160517/jetty-servlet-9.3.9.v20160517.jar:/Users/afarber/.m2/repository/org/eclipse/jetty/jetty-security/9.3.9.v20160517/jetty-security-9.3.9.v20160517.jar:/Users/afarber/.m2/repository/org/eclipse/jetty/websocket/websocket-api/9.3.9.v20160517/websocket-api-9.3.9.v20160517.jar:/Users/afarber/.m2/repository/org/eclipse/jetty/websocket/websocket-server/9.3.9.v20160517/websocket-server-9.3.9.v20160517.jar:/Users/afarber/.m2/repository/org/eclipse/jetty/websocket/websocket-common/9.3.9.v20160517/websocket-common-9.3.9.v20160517.jar:/Users/afarber/.m2/repository/org/eclipse/jetty/websocket/websocket-client/9.3.9.v20160517/websocket-client-9.3.9.v20160517.jar:/Users/afarber/.m2/repository/org/eclipse/jetty/websocket/websocket-servlet/9.3.9.v20160517/websocket-servlet-9.3.9.v20160517.jar \
de.afarber.MyServlet

作为轻微的可读性改进,我想在一个单独的变量中列出 -classpath 之后的所有路径,每个路径在另一个之后对齐:

PATHS=  /Users/afarber/src/jetty-newbie/EmbeddedWebsocket/target/classes \
        /Users/afarber/.m2/repository/org/eclipse/jetty/jetty-server/9.3.9.v20160517/jetty-server-9.3.9.v20160517.jar \
        /Users/afarber/.m2/repository/javax/servlet/javax.servlet-api/3.1.0/javax.servlet-api-3.1.0.jar \
        /Users/afarber/.m2/repository/org/eclipse/jetty/jetty-http/9.3.9.v20160517/jetty-http-9.3.9.v20160517.jar \
        /Users/afarber/.m2/repository/org/eclipse/jetty/jetty-util/9.3.9.v20160517/jetty-util-9.3.9.v20160517.jar \
        /Users/afarber/.m2/repository/org/eclipse/jetty/jetty-io/9.3.9.v20160517/jetty-io-9.3.9.v20160517.jar \
        /Users/afarber/.m2/repository/org/eclipse/jetty/jetty-servlet/9.3.9.v20160517/jetty-servlet-9.3.9.v20160517.jar \
        /Users/afarber/.m2/repository/org/eclipse/jetty/jetty-security/9.3.9.v20160517/jetty-security-9.3.9.v20160517.jar \
        /Users/afarber/.m2/repository/org/eclipse/jetty/websocket/websocket-api/9.3.9.v20160517/websocket-api-9.3.9.v20160517.jar \
        /Users/afarber/.m2/repository/org/eclipse/jetty/websocket/websocket-server/9.3.9.v20160517/websocket-server-9.3.9.v20160517.jar \
        /Users/afarber/.m2/repository/org/eclipse/jetty/websocket/websocket-common/9.3.9.v20160517/websocket-common-9.3.9.v20160517.jar \
        /Users/afarber/.m2/repository/org/eclipse/jetty/websocket/websocket-client/9.3.9.v20160517/websocket-client-9.3.9.v20160517.jar \
        /Users/afarber/.m2/repository/org/eclipse/jetty/websocket/websocket-servlet/9.3.9.v20160517/websocket-servlet-9.3.9.v20160517.jar 

这样我可以更轻松地添加和删除路径,并将它们排序为 Vim。

我的问题是:如何让他们加入我的命令?

更新:

如果所有 JAR 文件都位于同一个目录中,我可以使用 the new Java 8 wildcard syntax java -classpath "/that/dir/*" de.afarber.MyServlet - 但这里不是这种情况。

我建议使用 heredoc 来轻松维护这一长串 class 路径:

#!/bin/bash

# populate array cpath with all the the classpaths each one on different lines
read -d '' -ra cpath<<'EOF'
/Users/afarber/src/jetty-newbie/EmbeddedWebsocket/target/classes
/Users/afarber/.m2/repository/org/eclipse/jetty/jetty-server/9.3.9.v20160517/jetty-server-9.3.9.v20160517.jar
/Users/afarber/.m2/repository/javax/servlet/javax.servlet-api/3.1.0/javax.servlet-api-3.1.0.jar
/Users/afarber/.m2/repository/org/eclipse/jetty/jetty-http/9.3.9.v20160517/jetty-http-9.3.9.v20160517.jar
/Users/afarber/.m2/repository/org/eclipse/jetty/jetty-util/9.3.9.v20160517/jetty-util-9.3.9.v20160517.jar
/Users/afarber/.m2/repository/org/eclipse/jetty/jetty-io/9.3.9.v20160517/jetty-io-9.3.9.v20160517.jar
/Users/afarber/.m2/repository/org/eclipse/jetty/jetty-servlet/9.3.9.v20160517/jetty-servlet-9.3.9.v20160517.jar
/Users/afarber/.m2/repository/org/eclipse/jetty/jetty-security/9.3.9.v20160517/jetty-security-9.3.9.v20160517.jar
/Users/afarber/.m2/repository/org/eclipse/jetty/websocket/websocket-api/9.3.9.v20160517/websocket-api-9.3.9.v20160517.jar
/Users/afarber/.m2/repository/org/eclipse/jetty/websocket/websocket-server/9.3.9.v20160517/websocket-server-9.3.9.v20160517.jar
/Users/afarber/.m2/repository/org/eclipse/jetty/websocket/websocket-common/9.3.9.v20160517/websocket-common-9.3.9.v20160517.jar
/Users/afarber/.m2/repository/org/eclipse/jetty/websocket/websocket-client/9.3.9.v20160517/websocket-client-9.3.9.v20160517.jar
/Users/afarber/.m2/repository/org/eclipse/jetty/websocket/websocket-servlet/9.3.9.v20160517/websocket-servlet-9.3.9.v20160517.jar
EOF

# merge them with : as separator in classpath    
printf -v classpath "%s:" "${cpath[@]}"

# execute the java command line
/Library/Java/JavaVirtualMachines/jdk1.8.0_45.jdk/Contents/Home/bin/java \
-classpath "${classpath%:}" de.afarber.MyServlet

由于您使用的是 bash,因此您可以将目录名称存储在一个数组中(进行一些重构只是为了使该示例更具可读性):

repo=/Users/afarber/.m2/repository
jetty="$repo/org/eclipse/jetty"
websocket="$jetty/websocket"
paths=(
    /Users/afarber/src/jetty-newbie/EmbeddedWebsocket/target/classes
    "$jetty"/jetty-server/9.3.9.v20160517/jetty-server-9.3.9.v20160517.jar
    $repo/javax/servlet/javax.servlet-api/3.1.0/javax.servlet-api-3.1.0.jar
    "$jetty"/jetty-http/9.3.9.v20160517/jetty-http-9.3.9.v20160517.jar
    "$jetty"/jetty-util/9.3.9.v20160517/jetty-util-9.3.9.v20160517.jar
    "$jetty"/jetty-io/9.3.9.v20160517/jetty-io-9.3.9.v20160517.jar
    "$jetty"/jetty-servlet/9.3.9.v20160517/jetty-servlet-9.3.9.v20160517.jar
    "$jetty"/jetty-security/9.3.9.v20160517/jetty-security-9.3.9.v20160517.jar
    "$websocket"/websocket-api/9.3.9.v20160517/websocket-api-9.3.9.v20160517.jar
    "$websocket"/websocket-server/9.3.9.v20160517/websocket-server-9.3.9.v20160517.jar
    "$websocket"/websocket-common/9.3.9.v20160517/websocket-common-9.3.9.v20160517.jar
    "$websocket"/websocket-client/9.3.9.v20160517/websocket-client-9.3.9.v20160517.jar
    "$websocket"/websocket-servlet/9.3.9.v20160517/websocket-servlet-9.3.9.v20160517.jar 
)

请注意,您不需要以反斜杠结束每一行;空格(包括换行符)分隔数组的元素。获得数组后,您可以使用参数扩展和 IFS 参数的修改值将元素与冒号连接起来。

/Library/Java/JavaVirtualMachines/jdk1.8.0_45.jdk/Contents/Home/bin/java \
  -classpath "$(IFS=:; echo "${paths[*]}")" de.afarber.MyServlet

一个 sed 应该可以解决问题:

colonPATHS=$(echo "$PATHS" | sed -r 's/\s+/:/g') 
echo "$colonPATHS"

sed 将空白序列变成“:”。

简单sed就可以做到

pathwithcolons=`echo $PATHS|sed 's/ \+\ \+/:/g'`

我最终使用了 the following script:

#!/bin/sh

REPO=/Users/afarber/.m2/repository
VERSION=9.3.9.v20160517

CPATHS=/Users/afarber/src/jetty-newbie/WebsocketServlet/target/classes 
CPATHS=$CPATHS:$REPO/javax/servlet/javax.servlet-api/3.1.0/javax.servlet-api-3.1.0.jar 
CPATHS=$CPATHS:$REPO/org/eclipse/jetty/jetty-http/$VERSION/jetty-http-$VERSION.jar 
CPATHS=$CPATHS:$REPO/org/eclipse/jetty/jetty-io/$VERSION/jetty-io-$VERSION.jar 
CPATHS=$CPATHS:$REPO/org/eclipse/jetty/jetty-security/$VERSION/jetty-security-$VERSION.jar 
CPATHS=$CPATHS:$REPO/org/eclipse/jetty/jetty-server/$VERSION/jetty-server-$VERSION.jar 
CPATHS=$CPATHS:$REPO/org/eclipse/jetty/jetty-servlet/$VERSION/jetty-servlet-$VERSION.jar 
CPATHS=$CPATHS:$REPO/org/eclipse/jetty/jetty-util/$VERSION/jetty-util-$VERSION.jar 
CPATHS=$CPATHS:$REPO/org/eclipse/jetty/websocket/websocket-api/$VERSION/websocket-api-$VERSION.jar
CPATHS=$CPATHS:$REPO/org/eclipse/jetty/websocket/websocket-client/$VERSION/websocket-client-$VERSION.jar 
CPATHS=$CPATHS:$REPO/org/eclipse/jetty/websocket/websocket-common/$VERSION/websocket-common-$VERSION.jar 
CPATHS=$CPATHS:$REPO/org/eclipse/jetty/websocket/websocket-server/$VERSION/websocket-server-$VERSION.jar 
CPATHS=$CPATHS:$REPO/org/eclipse/jetty/websocket/websocket-servlet/$VERSION/websocket-servlet-$VERSION.jar 

/Library/Java/JavaVirtualMachines/jdk1.8.0_45.jdk/Contents/Home/bin/java \
        -classpath $CPATHS de.afarber.MyServlet

我比其他解决方案更喜欢它,因为它不会产生额外的进程(如 sed),更易于阅读并且可以转换为 Windows CMD 批处理文件:

@echo off

set REPO="C:\Users\user1\.m2\repository"
set VERSION=9.3.9.v20160517

set CPATHS=C:\Users\user1\jetty-newbie\WebsocketServlet\target\classes
set CPATHS=%CPATHS%;%REPO%\javax\servlet\javax.servlet-api.1.0\javax.servlet-api-3.1.0.jar
set CPATHS=%CPATHS%;%REPO%\org\eclipse\jetty\jetty-http\%VERSION%\jetty-http-%VERSION%.jar
set CPATHS=%CPATHS%;%REPO%\org\eclipse\jetty\jetty-io\%VERSION%\jetty-io-%VERSION%.jar
set CPATHS=%CPATHS%;%REPO%\org\eclipse\jetty\jetty-security\%VERSION%\jetty-security-%VERSION%.jar
set CPATHS=%CPATHS%;%REPO%\org\eclipse\jetty\jetty-server\%VERSION%\jetty-server-%VERSION%.jar
set CPATHS=%CPATHS%;%REPO%\org\eclipse\jetty\jetty-servlet\%VERSION%\jetty-servlet-%VERSION%.jar
set CPATHS=%CPATHS%;%REPO%\org\eclipse\jetty\jetty-util-ajax\%VERSION%\jetty-util-ajax-%VERSION%.jar
set CPATHS=%CPATHS%;%REPO%\org\eclipse\jetty\jetty-util\%VERSION%\jetty-util-%VERSION%.jar
set CPATHS=%CPATHS%;%REPO%\org\eclipse\jetty\websocket\websocket-api\%VERSION%\websocket-api-%VERSION%.jar
set CPATHS=%CPATHS%;%REPO%\org\eclipse\jetty\websocket\websocket-client\%VERSION%\websocket-client-%VERSION%.jar
set CPATHS=%CPATHS%;%REPO%\org\eclipse\jetty\websocket\websocket-common\%VERSION%\websocket-common-%VERSION%.jar
set CPATHS=%CPATHS%;%REPO%\org\eclipse\jetty\websocket\websocket-server\%VERSION%\websocket-server-%VERSION%.jar
set CPATHS=%CPATHS%;%REPO%\org\eclipse\jetty\websocket\websocket-servlet\%VERSION%\websocket-servlet-%VERSION%.jar
set CPATHS=%CPATHS%;%REPO%\org\postgresql\postgresql.4.1208.jre7\postgresql-9.4.1208.jre7.jar

"C:\Program Files\Java\jdk1.8.0_66\bin\java.exe" -cp %CPATHS% de.afarber.MyServlet