正規表示式檢查命令參數

正規表示式檢查命令參數

我想用來檢查運行的grep命令是否包含該單字作為參數。 (我知道 Bash 中的有關,我不想使用它)。cmdname!*

假設我有一個名為 的變數中的命令process

起初我嘗試過echo $process | grep 'cmd name'。這還不夠完善,因為它只考慮了一個參數。

所以我嘗試看看是否可以使用 regex 將其捕獲為最後一個參數cmd .*(?= )name。這個想法是捕獲任何內容,然後是一個空格,然後是name(after 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 arguments將被解析為兩個分離strings"somearguments",這是您永遠不想將命令及其參數儲存在單一字串中的原因之一。這也意味著它將檢測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(and dash,但也bash包括任何其他 POSIX shell),上面的內容就不那麼囉嗦了:

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

這本質上與第一段程式碼相同,但正確處理所有參數(引用等),因為我們從不將命令列的所有元素組合成單一文字字串。

答案2

既然你提到了 bash,另一個選擇是它的模式匹配運算子=~

if [[ $process =~ ^cmd[[:space:]].*name([[:space:]]|$) ]]
then
  _name_ was found as an argument to _cmd_
fi

這會查看變數的內容是否以 開頭cmd,後面跟著空格,後面跟著任何內容或無內容,後面跟著name,後面是:空格或行尾。

相關內容