2017-04-20 11 views
0

私はgrepがスクリプト内で動作していない

#!/bin/ksh 
while [[ $1 = -* ]] 
do 
    case $1 in 
     --data) 
      shift 
      ARGS="$ARGS -e \"$1\"" 
     ;; 
     --excl) 
      ARGS="-v $ARGS" 
     ;; 
    esac 
    shift 
done 
echo "grep $ARGS data.csv > test.txt" 
grep $ARGS data.csv > test.txt 

demo.kshとデータとしてフィルタアウトデータ用のスクリプトdemo.kshを書いています

data1,text1,text01 
data2,text2,text02 
data3,text3,text03 
data4,text4,text04 
data5,text5,text05 
data6,text6,text06 
data7,text7,text07 
data8,text8,text08 
data9,text9,text09 

として、私はdemo.csvファイルを持っています同じdir.demo.kshに.CSVある持って+ X私は

demo.ksh --data data3 

出力としてdemo.ksh実行permission.when: demo.ksh --data data3 < - スクリプトにエコーがあるため

test.txtは空白です(?なぜか分かりません) コンソール上にdemo.kshのエコーが表示され、コンソールに直接表示されたコマンドをコピーしてEnterキーを押すと、正常に動作し、test.txtを

data3,text3,test03 

というように生成します。シェルスクリプト内で何かが見つからない、または間違った方法でgrepを実行していますか?

+0

シェルスクリプトで '--data'の前後に引用符を追加するとどうなりますか?また、あなたはargとして$ 1を使用しています、あなたはargとして$ 2を使うべきです。 – SMA

+0

それはいいと思います。 echo "grep $ ARGS data.csv> test.txt"の出力をスクリプトから直接cmdに実行すると、正常に動作します。 – Jai

+0

このようにすることはできません。あなたは引数 'data3'ではなく、文字引数' 'data3" 'を' 'grep'に渡しています。そしてgrepはデータの二重引用符と一致させようとしています。ここでの引用は何もしておらず、実際にあなたのスクリプト 'demo.ksh --data 'foo bar''を呼び出した場合、grepは' 'bar''というファイルの文字列 '' foo'を探します。 ! 'grep -e '" foo "bar" data.csv "を呼び出すのと同じです。 –

答えて

0

-vスイッチは次の文字列だけでなくすべてを無効にします。重複する-vスイッチは、スイッチ-vのように動作します。 -vスイッチを$ARGに追加すると、偶然でなければ、1つの文字列に対してローカルな否定を行うことはできません。

$ARGSは、検索文字列を保持するために2つの別々の入力ファイルを使用することを検討して、正の正規表現と否定的なものの組み合わせを含めることはできませんので:

#!/bin/ksh 
pos=`mktemp` 
neg=`mktemp` 
while [ "$1" ] 
do 
    case $1 in 
     --data) 
      shift 
      echo "$1" >> $pos 
     ;; 
     --excl) 
      shift 
      echo "$1" >> $neg 
     ;; 
    esac 
    shift 
done 
grep -f $pos data.csv | grep -v -f $neg > test.txt 
rm $pos $neg 

注意をdemo.kshの構文はそのまま残されているが、それはです前に--exclまたは--dataのない検索文字列またはファイル名が失われるため、あまり良い構文ではありません。

関連する問題