2012-05-07 15 views
3

でのgrepの-vは、私はこのls |スクリプト

(in pseudo) 
    for each item in excludelist 
     append to string: | grep -v $item 

    for each file in directory 
    do 
     stuff 
    done 

となりまし

(in real code, the creation and concatenation of f works, the problem is not here I believe) 
    for i in $EXCLUDE 
    do 
     echo $i 
     f="$f | grep -v $i" 
    done 

    for d in `ls $AWSTATSCONF/awstats*conf $f` 
    do 
     echo $d 
    done 

出力

ls: |: No such file or directory 
    ls: grep: No such file or directory 

に本当に得るために感謝任意およびすべてのヘルプをしたいbashスクリプトを持っていますこれはうまくいく。

挨拶、

シャドウ

+0

'f = $(echo" $ f "| grep -v" $ i ")'はうまく動作しますか? – VonC

+0

しかし、その部分は動作します。 問題はlsの実行にあります。 – ShadowFlame

+0

'ls'試行は' 'grep' 'にアクセスすることを考慮すると、私はその部分がうまく機能するとは思わない。 – VonC

答えて

0

あなたは$fgrepの*出力を追加する必要があります。 (|とgrepは、カレントディレクトリで発見されていないもちろん)

$f = "$f $(grep -v $i)" 
+0

私は私の質問を誤って書いたと信じています。 私が信じる問題のある部分は、lpsで、grepsの作成ではありません。 – ShadowFlame

0

問題は、プレーンは、lsコマンドの引数をエスケープとしてfoo whatever whatever elseが実行されていることです。 evalはに次のFAQを確認し、これは賢明なワームのセキュリティの大きな缶を開くことに注意してくださいあなたは、次の

for d in `eval "ls $AWSTATSCONF/awstats*conf $f"` 
do 
    echo $d 
done 

のような何かをする必要がありbashコマンド

として文字列を実行コマンドであります他の選択肢についてもっと理解してください。

+0

問題ありません。専門家のみが内部使用しています。ウェブフロントエンドなどはありません。しかし、警告ありがとう:-) – ShadowFlame

0

for i in $(ls)を使用しないでください。グロビングを使用する必要があります。

連結を使用して、grep -vという長い文字列を作成しないでください。

$EXCLUDEはどこから来たのですか?文字列ではなく配列でなければなりません。

for d in "$AWSTATSCONF"/awstats*conf 
do 
    for e in "${exclude[@]}" 
    do 
     if [[ $d != $e ]] 
     then 
      echo "$d" 
     fi 
    done 
done 
+0

EXCLUDE = "string1 string2 string3" – ShadowFlame

2

あなたbashを使っているので、あなたはあなたの除外リストを除外するためにpattern matchingを使用することができます。

pattern=$(awk ' BEGIN {OFS="|"; printf("!(")} 
       {$1=$1; printf("%s",$0)} 
       END {print ")"} 
       ' <<< $EXCLUDE) 
shopt -s extglob 
for d in $pattern; do 
    echo $d 
done  
2

それに対処するための多くの方法があります。

lsの出力を解析することに不安があります。どのように正当化されるかは、可能なすべてのファイル名(空白や改行を含むものは特に問題があります)や、移植可能なファイル名の文字セットを使用する通常のファイル名を持っているかどうかによって異なります(POSIXに従って(ラテン)アルファベット、数字、プラス.-、および_)。

、あなたはあなたが望んでいた効果を得ることができる、あなただけのポータブルファイル名に対処する必要があると仮定すると:

それは内パイプなどの文字列 $fにパイプを治療するためのシェルを強制するよう evalを使用して
for i in $EXCLUDE 
do 
    echo $i 
    f="$f | grep -v $i" 
done 

for d in `eval ls $AWSTATSCONF/awstats*conf $f` 
do 
    echo $d 
done 

シェル。 にご相談ください:evalは強力で危険なツールです。

除外する用語が20個ある場合、20個のgrepを順番に実行するために選択されたメカニズムは、多くのプロセスを使用します。デモの目的ではそれほど深刻ではないでしょうが、制作作業や何千ものファイルを扱っているのであれば、あまり良くありません。あなたはおそらくegrep(またはgrep -E)コマンドの構築を見てみたいと思います

f="antidisestablishmentarianism" 
for i in $EXCLUDE 
do 
    f="$f|$i" 
done 

ls $AWSTATSCONF/awstats*conf | 
egrep -v "$f" | 
while read d 
do echo $d 
done 

私ははい、それはです(あなたの周りに潜んでいる「antidisestablishmentarianism」を含む名前のいずれかの統計情報ファイルを持っていないと仮定します現実の言葉であり、ここではほとんどが冗談として使われている)。

while readの配合は、forループを書き込む別の方法です。サブプロセスが親シェルの変数に影響を与えないように注意してください。つまり、whileループはメインシェルではなく、サブシェルによって処理されるため、メインシェルで変数を設定するループに頼っていれば、それは動作しません。—とすることができます。 forループ。しかし、あなたは再びevalを必要としません:

for d in $(ls $AWSTATSCONF/awstat*conf | egrep -v "$f") 
do 
    echo $d 
done 

一般的に良いアイデアですバッククォートの代わりに$(...)を使用します。