명령 인수를 확인하는 정규식

명령 인수를 확인하는 정규식

grep실행된 명령에 해당 cmd단어가 name인수로 포함되어 있는지 확인하는 데 사용하고 싶습니다 . (Bash에 대해 알고 있지만 !*사용하고 싶지 않습니다.)

라는 변수에 명령이 있다고 가정해 보겠습니다 process.

처음에는 echo $process | grep 'cmd name'. 이는 하나의 인수만 고려하기 때문에 충분히 정제되지 않았습니다.

그래서 정규식을 사용하여 마지막 인수로 캡처할 수 있는지 확인하려고 했습니다 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"is 인 경우 나머지 명령줄에서 cmd검색해야 한다는 것을 알 수 있습니다 . name그렇지 않다면 거기서 멈추겠습니다.

위치 매개변수 목록에서 shift벗어나 루프 의 인수를 살펴보기 시작합니다. cmd각 반복에서 인수를 문자열과 비교하기만 하면 됩니다 name. 찾으면 그렇게 말하고 종료합니다.

루프가 끝나면 name인수를 찾지 못했다는 것을 알게 되므로 이를 보고하고 실패로 종료합니다.

위의 예에서 인수는 some arguments두 가지로 구문 분석됩니다.분리된"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및 기타 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

이는 기본적으로 첫 번째 코드 조각과 동일하지만 명령줄의 모든 요소를 ​​단일 텍스트 문자열로 결합하지 않기 때문에 모든 인수(인용 등)를 올바르게 처리합니다.

답변2

bash를 언급했으므로 또 다른 옵션은 패턴 일치 연산자입니다 =~.

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

cmd이는 변수의 내용이 로 시작하고 , 공백이 뒤따르고, 아무 것도 아니면 아무것도 뒤따르지 않고, 그 뒤에 name공백이나 줄의 끝이 오는지 확인합니다 .

관련 정보