我想用來檢查運行的grep
命令是否包含該單字作為參數。 (我知道 Bash 中的有關,我不想使用它)。cmd
name
!*
假設我有一個名為 的變數中的命令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"some
和arguments"
,這是您永遠不想將命令及其參數儲存在單一字串中的原因之一。這也意味著它將檢測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
,後面是:空格或行尾。