2011-10-11 30 views
31

私はbashスクリプトでは、このような長いコマンドを埋め込むしたいと思います:砕き、長いファイル名を持つ非常に長い文字列リテラルをbashで分割するにはどうしたらいいですか?

mycommand \ 
    --server myserver \ 
    --filename extremely/long/file/name/that/i/would/like/to/be/able/to/break/up/if/possible \ 
    --otherflag \ 
    --anotherflag 

を。

# Insufficiently pretty 
mycommand \ 
    --server myserver \ 
    --filename extremely/long/file/name/\ 
that/i/would/like/to/be/able/to/break/\ 
up/if/possible \ 
    --otherflag \ 
    --anotherflag \ 

をそれが流れを壊す:

私はこれを行うことができます。私はのように書くことができるようになります

# Doesn't work 
mycommand \ 
    --server myserver \ 
    --filename extremely/long/file/name/\ 
     that/i/would/like/to/be/able/to/break/\ 
     up/if/possible \ 
    --otherflag \ 
    --anotherflag 

をしかし、それは文字列リテラルを壊すので、それは動作しません。

bashに文字列リテラルを壊すように指示する方法はありますか?先頭のスペースは無視しますか?

答えて

36

あなたは変数を使用することができます。

file=extremely/long/file/name 
file+=/that/i/would/like/to/be/able/to/break 
file+=/up/if/possible 

mycommand\ 
    --server myserver\ 
    --filename $file\ 
    --flag flag 
+6

良いアイデア。 'file = $ {file}/... 'の代わりに' + = '演算子を使うと、よりきれいにすることができます。 – Chriszuma

+5

+1:これは私の意見では最も難解なアプローチです。その意図ははっきりしています。 –

+0

@Chriszumaはい、私はbashが '+ ='演算子を許しているのを忘れていました。私は私の答えを編集しました。 – WilQu

36

それはハックの 少しですが、この作品:

mycommand \ 
    --server myserver \ 
    --filename "extremely/long/file/name/"` 
       `"that/i/would/like/to/be/able/to/break/"` 
       `"up/if/possible" \ 
    --otherflag \ 
    --anotherflag 

バッシュが隣接している文字列リテラルを連結して、私たちはそれを活用します。たとえば、echo "hi" "there"hi thereを、echo "hi""there"hithereを印刷します。

また、バックティック演算子と空白の束が何も評価されないという事実を利用しています。

+2

'\'行の代わりに、 '\'を前の行の末尾に置くことができます。それは左端をきれいに保ちます。 –

+0

良いコール、それについては考えていませんでした。 Dulyは編集しました。 – Chriszuma

1

基本的には、これを行うにはbashに組み込まれたものは何もありません。
ラッパーは、通常、それが価値があるよりも厄介ですが、それはエイリアスやファンクションを試すことができると言いました。 j

j(){sed -e ':a;$!N;s/ *\n *//g;ta' <<<"$1"} 

echo "$(j "3 spaces 
      /hello 
      /world 
      /this 
      /is 
      /a 
      /long 
      /path 
      ")" 

# 3 spaces/hello/world/this/is/a/long/path 
3

私はbashスクリプトの先頭に短いstrcatの関数を定義し、物事を分割するインライン呼び出しを使用します。コマンド呼び出しで長いリテラルをインラインで定義することができるので、別の変数を使用することを好みます。

function strcat() { 
    local IFS="" 
    echo -n "$*" 
} 

mycommand \ 
    --server myserver \ 
    --filename "$(strcat \ 
     extremely/long/file/name/ \ 
     that/i/would/like/to/be/able/to/break/ \ 
     up/if/possible)" \ 
    --otherflag \ 
    --anotherflag \ 

私も、私は私が値の間にカンマを入力しないようにそれを使用することができますので、フラグパラメータとして値の長いCSVを入力する必要がある場合は、このアプローチのように:

function strjoin() { 
    local IFS="$1" 
    shift 
    echo -n "$*" 
} 

csv_args=(
    foo=hello 
    bar=world 
    "this=arg has spaces in it" 
) 
mycommand \ 
    --server myserver \ 
    --csv_args "$(strjoin , "${csv_args[@]}")" \ 
    --otherflag \ 
    --anotherflag \ 

同等です

mycommand \ 
    --server myserver \ 
    --csv_args "foo=hello,bar=world,this=arg has spaces in it" \ 
    --otherflag \ 
    --anotherflag \ 
1

一つ可変配列を使用することができ

file=(extremely/long/file/name 
    /that/i/would/like/to/be/able/to/break 
    /up/if/possible) 
IFS='' 

echo mycommand\ 
    --server myserver\ 
    --filename "${file[*]}"\ 
    --flag flag 
関連する問題