2016-05-03 8 views
0

私はこれが簡単だと確信していますが、私はbashスクリプトが新しく、ここでは構文的なプロセスが私を超えています。私は必要なものを見つけるための正しい検索条件を見つけることができないようです。このスクリプトは実際に私の最終版への足がかりにすぎません。Bash - ネストされた変数展開のコマンド割り当て内

呼び出し:TESTFILEを./myscript.sh

スクリプト:

#!/bin/bash 

file=$1 
awk='{print $9}' # do not expand $9 
awk="'/$file/$awk'" # DO expand file argument 
echo "$awk" # prints '/graphic/{print $9}' (as expected) 
echo "ls -l | awk $awk" # prints ls -l | awk '/graphic/{print $9}' (as expected) 
test="$(ls -l | awk $awk)" # error 
echo "$test" 

出力:

'/testFile/{print $9}' 
ls -l | awk '/testFile/{print $9}' 
awk: syntax error at source line 1 
context is 
    >>> ' <<< 
    missing } 
awk: bailing out at source line 1 

私はコピーして、第二echo'dラインを実行し、それが動作することができたとしてもコマンドの失敗は、これが単純な文字列連結ではなく、いくつかの狂気のブードゥーであると信じさせてくれます。

私は、コマンド全体を含む変数を作るのと同じようにいくつかの他のバージョンを試しましたが、それから出力があまり期待できません。

私はテスト= "$($のAWK)"は私がテスト= $(awkの)をすれば、私は私のグーグル以来

'/testFile/{print $9}' 
ls -l | awk '/testFile/{print $9}' 
usage: awk [-F fs] [-v var=value] [-f progfile | 'prog'] [file ...] 

を取得

'/testFile/{print $9}' 
ls -l | awk '/testFile/{print $9}' 
ls: $9}': No such file or directory 
ls: '/testFile/{print: No such file or directory 
ls: awk: No such file or directory 
ls: |: No such file or directory 

を取得しない場合クエリには基本的に「bashコマンド変数の代入」という言葉しか含まれていないので、ここにある入れ子になった変数の拡張に関連するものは得られません。私はそれがエラーに基づいて何をしているのか理解していますが、それを修正する理由や方法は言えませんでした。

誰かが修正プログラムを提供するだけでなく、ここで何が起こっているのかを説明するリソースを私に指摘してもらえれば、非常に感謝しています。あるいは、論理を単純化する別のアプローチがあるかもしれません。

ありがとうございます!

+0

'set -x'とhttp://www.shellcheck.netはお友達です。 – Biffen

+0

クールな設定-xは、エスケープされた一重引用符が追加されていることを明らかにしているようです...質問はそれを修正する方法です... – Liandri

+0

私は何か働いています(テスト= "$(ls -l | awk" $ awk " ) ")しかし、この間違いを避ける方法については、もう少し勉強する必要があります。文字列変数は引用符でのみ定義されるのではなく、後で使用するときには引用符で囲まれているようです。だから、私は自分のコマンドがどのように引用されているかを直接制御することはできません。 – Liandri

答えて

1

変更:

test="$(ls -l | awk "$awk")" # error 

awkは、単一の引数であることをスクリプトが必要です。しかし、あなたは二重引用符の外の変数を展開すると、シェルは単語分割を行い、その$awkは二つの引数に展開されています

  1. '{print
  2. $9}'

引用符が1つの引数として拡大を続けます。

また、単一引用符は、変数を展開した後に処理されていないので、彼らはawkに文字通り渡されます

awk="'/$file/$awk'" 

のうち、単一引用符を取ります。 $awkの前後に二重引用符を入れると、引用符で取得しようとした結果が得られます。

関連する問題