正規表現チェックコマンドパラメータ

正規表現チェックコマンドパラメータ

grep実行中のコマンドにその単語が引数として含まれていることを確認するために使用したいと思います。 (私はBashでそれについて知っていますが、使用したくありません)。cmdname!*

という変数にコマンドがあるとしましょうprocess

最初はecho $process | grep 'cmd name'。これは1つのパラメータしか考慮しないため、完璧ではありません。

そのため、regexを使用して最後のパラメータとしてキャプチャできるかどうかを調べようとしましたcmd .*(?= )name。アイデアは何でもキャプチャしてからスペースとname(次のcmd)をキャプチャすることです。しかし、これはうまくいきません。

これがうまくいけば、私の目標は、あらゆる立場で議論として解釈しようとすることです。

正規表現を使用してこれをどのように実行できますか?

ベストアンサー1

以下の回答では、grepコマンドラインは個々のアイテムのリストなので、テキスト行ではなくそのまま解析する必要があります。


コマンドとコマンドの引数の両方を単一の文字列(好ましくは配列)に格納するとします。変数に保存されたコマンドをどのように実行できますか?)これにより、次のことができます。

process='cmd with "some arguments" and maybe name'

set -f
set -- $process

if [ "$1" != 'cmd' ]; then
    echo 'The command is not "cmd"'
    exit 1
fi

shift

for arg do
    if [ "$arg" = 'name' ]; then
        echo 'Found "name" argument'
        exit
    fi
done

echo 'Did not find "name" argument in command line'
exit 1

これにより、最初にファイル名の生成が無効になります。これは、ファイル名$processを引用符なしで別々の単語に分割し、文字列にファイル名のグローブパターン(など)が*含まれていると、解析がめちゃくちゃになるためです。私たちはこのようなことをしていますset -f

次に、位置パラメータをの単語に設定します$process。その後、そうであれば、"$1"コマンドラインの残りの部分をcmd見なければならないことを知っています。nameそうでない場合は、ここで停止します。

位置パラメータのリストをshiftそのままにして、パラメータを介して繰り返しを開始します。cmd各反復では、単に引数を文字列と比較しますname。それを見つけたら、私たちは言ってやめます。

ループが終了すると、まだパラメータが見つからなかったことがわかるので、nameこれを報告して失敗で終了します。

上記の例では、パラメータはsome arguments2つに解析されています。分離strings"somearguments"、これがコマンドとその引数を単一の文字列に格納したくない理由の1つです。これはまた、name単一のパラメータ内でパラメータを検出することを意味し"some name string"、これは偽陽性になります。


コマンドラインが配列(たとえばbash)に保存されている場合は、次のことができます。

process=( cmd with "some arguments" and maybe name )

if [ "${process[0]}" != 'cmd' ]; then
    echo 'The command is not "cmd"'
    exit 1
fi

for arg in "${process[@]:1}"; do
    if [ "$arg" = 'name' ]; then
        echo 'Found "name" argument'
        exit
    fi
done

echo 'Did not find "name" argument in command line'
exit 1

拡張は"${process[@]:1}"完全な配列ですが、最初の項目(コマンド名)ではありません。

/bin/sh(anddashおよび他のPOSIXシェル)の場合、bash上記はあまり冗長ではありません。

set -- cmd with "some arguments" and maybe name

if [ "$1" != 'cmd' ]; then
    echo 'The command is not "cmd"'
    exit 1
fi

shift

for arg do
    if [ "$arg" = 'name' ]; then
        echo 'Found "name" argument'
        exit
    fi
done

echo 'Did not find "name" argument in command line'
exit 1

これは基本的に最初のコードと同じですが、コマンドラインのすべての要素を単一のテキスト文字列に結合しないため、すべての引数(引用符など)を正しく処理します。

おすすめ記事