나는이 문제가 생각보다 조금 덜 무해하다고 생각하는 것으로 시작하겠습니다.
내가해야 할 일 : PATH 환경 변수 내의 폴더를 확인하십시오. 그것은 시작이나 어딘가에있을 수 있습니다. 해당 폴더가 있는지 확인하기 만하면됩니다.
내 문제의 예-사용하자 /opt/gnome
.
시나리오 1 : 폴더가 PATH 시작 부분에 없습니다
# echo "$PATH"
/sbin:/usr/sbin:/opt/gnome:/var/opt/gnome
# echo "$PATH" | grep ":/opt/gnome"
/sbin:/usr/sbin:/opt/gnome:/var/opt/gnome
grep이 잡히지 않도록 충분히 구체적이어야합니다 /var/opt/gnome
. 따라서 결장.
시나리오 2 : 폴더가 PATH 시작에 있습니다.
# echo "$PATH"
/opt/gnome:/sbin:/usr/sbin:/var/opt/gnome
# echo "$PATH" | grep "^/opt/gnome"
/opt/gnome:/sbin:/usr/sbin:/var/opt/gnome
이것은 내 문제입니다.이 폴더로 콜론이나 줄 시작을 검색해야합니다. 내가하고 싶은 것은이 두 대괄호 표현 중 하나입니다.
# echo $PATH | grep "[^:]/opt/gnome"
# echo $PATH | grep "[:^]/opt/gnome"
하지만 [^
과 [:
자신의 의미를 가지고있다. 따라서 위의 두 명령이 작동하지 않습니다.
이 두 시나리오를 한 명령으로 grep 할 수있는 방법이 있습니까?
답변
PATH
파일에서 무언가를 찾는 것과는 달리 환경 변수 의 내용을 확인하는 grep
경우 잘못된 도구입니다. 쉘에서하는 것이 더 쉽고 빠르며 읽기 쉽다.
bash, ksh 및 zsh에서 :
if [[ :$PATH: = *:/opt/gnome:* ]]; then
: # already there
else
PATH=$PATH:/opt/gnome
fi
포터블 :
case :$PATH: in
*:/opt/gnome:*) :;; # already there
*) PATH=$PATH:/opt/gnome;;
esac
:$PATH:
오히려 사용 $PATH
; 이런 식으로 구성 요소는 시작 또는 끝에 있더라도 검색 문자열에서 항상 콜론으로 둘러싸입니다 $PATH
.
당신이 파일의 라인을 통해 검색하는 경우, 당신은 (즉, 필요로하는 확장 된 정규 표현식을 사용할 수 있습니다 grep -E
) (^|:)/opt/gnome($|:)
일치 /opt/gnome
하지만은 행의 시작 부분에 하나의 또는 콜론 다음, 그것은 말 중 하나의 경우에만 경우에만 줄 또는 그 뒤에 콜론이옵니다.
답변
다음을 사용하여 확장 정규식을 사용할 수 있습니다 grep -E
오 탐지를 피하려면 경로의 시작과 끝을 일치시켜야합니다.
처음에 인스턴스와 일치합니다.
$ TEST=/opt/gnome:/sbin:/usr/sbin:/var/opt/gnome
$ echo $TEST | grep -E "(:|^)/opt/gnome(:|$)"
/opt/gnome:/sbin:/usr/sbin:/var/opt/gnome
중간에있는 인스턴스와도 일치합니다.
$ TEST=/sbin:/usr/sbin:/opt/gnome:/var/opt/gnome
$ echo $TEST | grep -E "(:|^)/opt/gnome(:|$)"
/sbin:/usr/sbin:/opt/gnome:/var/opt/gnome
오 탐지 피하기 :
$ TEST="/home/bob/opt/gnome:/opt/gnome/somethingelse:/opt/gnome-beta"
$ echo $TEST | grep -E "(:|^)/opt/gnome(:|$)"
일치하는 항목이 없습니다.
작고 우아합니다. 데비안 7에서 테스트되었습니다.
답변
당신이 결혼하지 않은 경우에 grep
, 당신은 awk
에 기록을 사용 하고 분리 할 수 있습니다:
awk 'BEGIN {RS=":"} /^\/opt\/gnome$/'
답변
당신은 또한 사용할 수 있습니다
echo "$PATH" | tr ':' '\n' | grep -x "/opt/gnome"
경로 변수를 별도의 줄 (경로당 하나)로 분할하므로 grep -x
정확한 결과를 찾을 수 있습니다. 이것은 물론 추가 프로세스가 필요하다는 단점이 있습니다 tr
. 폴더 이름에 PATH
개행 문자 가 포함되어 있으면 작동하지 않습니다 .
답변
나는 대답하기에 충분하다는 것을 모른다.
grep -w "/opt/gnome"
당신의 필요를 만족시킬 것입니다.
echo '/sbin:/usr/sbin:/opt/gnome:/var/opt/gnome' | grep -w "/opt/gnome" -o
/opt/gnome
echo '/opt/gnome:/sbin:/usr/sbin:/var/opt/gnome' | grep -w "/opt/gnome" -o
/opt/gnome
그러나
echo '/opt/gnome:/sbin:/usr/sbin:/var/opt/gnome' | grep "/opt/gnome" -o
/opt/gnome
/opt/gnome
답변
선택합니다 /opt/gnome
(새로운 라인, 비 단어 문자로 둘러싸인 :
, /
등)이 하나를 시도해보십시오 :
grep '\B/opt/gnome'
답변
에 거의 노력을 기울이지 않고이 작업을 안정적으로 수행 할 수 있습니다 grep
. 광범위하게 사용 가능하고 이미 많은 솔루션이 제공되는 확장을 이용할 수 있지만 기본 정규 표현식을 사용하더라도 쉽게 수행 할 수는 있지만 처음에는 직관적이지 않을 수 있습니다.
기본 정규 표현식과 함께 grep
-항상 머리와 꼬리의 두 가지 신뢰할 수있는 앵커가 있습니다. 다음 과 같이 라인상의 위치에 관계없이 두 가지 모두에 일치 항목을 고정시킬 수 있습니다 .
grep '^\(ignore case, delimiter\)*match\(delimiter, ignore case\)*$'
grep
\(grouped\)
같은 방식으로 다음 구분 기호와 명시 적으로 일치하고 일치하는 꼬리에서 줄의 꼬리까지 발생 해야하는 만큼 많은 하위 표현식 이 줄의 머리 에서 일치합니다. 사용자의 명시 적 일치가 일치하지 않는 경우 명시 적으로 는 실패하고 아무것도 인쇄하지 않습니다.
예를 들어 다음과 같이 할 수 있습니다.
grep '^\(.*:\)*/opt/gnome\(:.*\)*$'
직접 참조하십시오 :
grep '^\(.*:\)*/opt/gnome\(:.*\)*$
' <<\INPUT
/opt/gnome-beta
/opt/gnome
/home/bob/opt/gnome
:/opt/gnome:
/home/bob/opt/gnome:/opt/gnome:/opt/gnome-beta
/opt-gnome-beta
/opt/gnomenot::::/opt/gnome
INPUT
산출
/opt/gnome
:/opt/gnome:
/home/bob/opt/gnome:/opt/gnome:/opt/gnome-beta
/opt/gnomenot::::/opt/gnome