2012-02-20 108 views
3

我想連接所有傳遞給我的bash腳本的參數,除了標誌。在bash腳本中連接輸入

因此,例如,如果腳本需要輸入如下:

./myBashScript.sh -flag1 exampleString1 exampleString2 

我想要的結果是「exampleString1_exampleString2」

我能爲輸入的預定數量做到這一點(即2) ,但我怎麼能做到這一點的任意數量的投入?

回答

2

這是一個醜陋的,但簡單的解決方案:

echo $* | sed -e "s/ /_/g;s/[^_]*_//" 
+1

和錯誤。你有沒有讀過這個問題? – 2012-02-20 01:32:30

+0

@JoSo:是的,這屬於它的(措辭不佳)規範。 – mvds 2012-02-20 01:35:07

+0

然而,你解釋規範,你的解決方案是錯誤的。它甚至不刪除任何參數。 – 2012-02-20 01:37:20

8
function concatenate_args 
{ 
    string="" 
    for a in "[email protected]" # Loop over arguments 
    do 
     if [[ "${a:0:1}" != "-" ]] # Ignore flags (first character is -) 
     then 
      if [[ "$string" != "" ]] 
      then 
       string+="_" # Delimeter 
      fi 
      string+="$a" 
     fi 
    done 
    echo "$string" 
} 

# Usage: 
args="$(concatenate_args "[email protected]")" 
+0

對不起,對於錯誤的外殼樣式(非常冗長而且'[[...]]'不是便攜式)是-1。使用'test'來替代我的解決方案來使用'$ {a:0:1}' – 2012-02-20 01:39:33

+0

@JoSo爲什麼'[[]]'不可移植? – Tyilo 2012-02-20 14:09:24

+0

這是bash,而不是POSIX sh。 (與'$ {a:0:1}'相同)。雖然有些人不關心,因爲bash幾乎安裝在任何系統上,在這種情況下,它真的沒有用(改用'test' alias'[']')。 – 2012-02-20 15:53:29

0
flag="$1" 
shift 
oldIFS="$IFS" 
IFS="_" 
the_rest="$*" 
IFS="$oldIFS" 

在此背景下,"$*"是你要找什麼,它似乎。它很少是正確的選擇,但是這是一個真正的選擇。

或者,簡單循環和連擊:

flag="$1" 
shift 
the_rest="" 
pad="" 
for arg in "[email protected]" 
do 
    the_rest="${the_rest}${pad}${arg}" 
    pad="_" 
done 

$pad變量確保你不以$the_rest開始流浪下劃線結束。

+0

O.P.如何在每個arg之間獲得所需的'_'? – shellter 2012-02-20 01:31:55

+1

您可以設置IFS,使其第一個字符包含'_'來影響'$ *'連接的行爲。 – 2012-02-20 01:33:53

2

這裏有一段代碼,實際上,我感到自豪的(這是很shell風格,我認爲)

#!/bin/sh 

firsttime=yes 
for i in "[email protected]" 
do 
    test "$firsttime" && set -- && unset firsttime 
    test "${i%%-*}" && set -- "[email protected]" "$i" 
done 

IFS=_ ; echo "$*" 

我理解你的問題,以去除所有參數開頭-

如果你只是想刪除的論點- beginnnig開始序列:

#!/bin/sh 

while ! test "${1%%-*}" 
do 
    shift 
done 

IFS=_ ; echo "$*" 

如果你只是想刪除的第一個參數:

#!/bin/sh 

shift 
IFS=_ ; printf %s\\n "$*" 
1

您還可以使用格式的字符串來連接ARGS。

# assuming flag is first arg and optional 
flag=$1 
[[ $1 = ${1#-} ]] && unset $flag || shift 

concat=$(printf '%s_' ${@}) 
echo ${concat%_} # to remove the trailing _ 

nJoy!