if thenステートメントとすべてのbashスクリプト

if thenステートメントとすべてのbashスクリプト

複数のファイルで特定の文字列を確認し、見つかった場合は削除するbashスクリプトを作成しようとしています。ここに私が持っているものがあり、それがうまくいくと思いますが、部分的にのみ可能です。ファイル内のエントリは削除されますが、2回目に実行すると「Nothing to do...」というメッセージは表示されません。

#!/bin/bash
files=(
        '/etc/rsyslog.conf'
        '/etc/rsyslog.d/remote.conf'
        '/etc/rsyslog.d/01-remote.conf'
)

tmpcheck="for f in ${files[*]}; do  cat $f | grep blah | wc -l; done"
#for f in ${files[*]}; do  cat $f | grep collector.acuity.com | wc -l; done

if [[ "$tmpcheck" != 1 ]];then
for f in "${files[@]}";do
                echo -e "Removing blah from $f"
                sed -i "/blah/d" "$f"
        done
                echo -e "Restarting rsyslog service"
                systemctl restart rsyslog.service
else
        echo -e "Nothing to do, blah has been removed from $f"
fi

どんな助けでも大きな助けになります。

ベストアンサー1

tmpcheckコードの主な問題(ペア割り当て)は他の回答で指摘されています。変更された/変更されていないファイルの名前を印刷することは必須ではないと仮定するいくつかの異なるアプローチは次のとおりです。

if grep -q -- blah "${files[@]}"
then
    sed -i -e '/blah/d' -- "${files[@]}"
    systemctl restart rsyslog.service
else
    printf '%s\n' 'Nothing to do'
fi

ここで主なアイデアは次のとおりです。

  • 必要でない場合は、出力を保存して後でテストするのではなく、複合コマンド内で直接コマンドの(grep)終了状態を使用してください。if
  • ループからユーティリティを呼び出すことはあまり効率的ではありません。可能な限り、複数のファイルを引数として使用して呼び出すのが最善です。

また、表示されるコードではこれらの問題は発生しませんが、次のことを行います。

  • オプションを閉じるタグ(--)を追加すると、異常なファイル名を防ぐことができます。
  • printf より安全特に拡張結果を印刷する場合はさらにそうですecho

おすすめ記事