피엔프Bash에 대한 다음 sed 명령이 있는 저장소:
sed -Ei -e '/^([^#]|$)/ {a \
export PYENV_ROOT="$HOME/.pyenv"
a \
export PATH="$PYENV_ROOT/bin:$PATH"
a \
' -e ':a' -e '$!{n;ba};}' ~/.profile
어떻게 작동하나요?
답변1
표시되는 명령은 파일에 두 줄의 텍스트를 추가합니다 ~/.profile
. 이 라인은
export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"
명령을 통해 추가됩니다 a
(GNU 명령은 한 줄에 한 번씩 사용되므로 sed
불필요합니다). 정규식이 일치하면 명령이 a
실행됩니다. 정규 표현식은 a
^([^#]|$)
#
시작하지 않거나 비어 있는 첫 번째 줄 과 일치합니다 . 행이 추가됩니다.뒤쪽에그 트리거 라인.
끝은 다음 줄을 읽고, 인쇄하고, 파일 끝까지 계속하여 문서의 나머지 부분을 그대로 유지하도록 허용하는 명시적 루프입니다. 이렇게 하면 정규식과 일치하는 각 줄 뒤에 두 줄의 텍스트를 추가하는 것을 방지하고 두 명령을 모두 실행합니다 a
.
이 명령은 수행할 작업을 파악하기 위해 약간의 분석이 필요하므로 다소 어색하게 작성되었습니다. 그 요점은 ~/.profile
초기 주석 블록 다음의 첫 번째 줄 이후에 파일에서 가능한 한 빨리 새 내용을 삽입하려고 시도한다는 것입니다. 주석 뒤의 첫 번째 줄 뒤에 줄을 추가하는 대신 주석 뒤에 줄을 추가하는 대신 i
사용해야 할 것입니다 .a
개인적으로 나는 단지끝스크립트:
cat >>"$HOME/.profile" <<'PYENV_SETUP_ENDS'
export PYENV_ROOT="$HOME/.pyenv"
PATH=$PYENV_ROOT/bin:$PATH
PYENV_SETUP_ENDS
( PATH
다시 내보낼 필요가 없습니다.)
최신 GNU에서는 다음 을 사용하여 명령을 복사 awk
할 수 있습니다 .sed
awk -i inplace '
{ print }
!a && (/^[^#]/ || length == 0) {
print "export PYENV_ROOT=\"$HOME/.pyenv\""
print "PATH=$PYENV_ROOT/bin:$PATH"
a = 1
}' ~/.profile
awk
초기 주석 블록 뒤의 첫 번째 줄 뒤에 줄을 추가하는 대신, 초기 주석 블록 뒤에 줄을 추가하려면 코드의 두 블록을 바꿉니다 .
동일한 GNU sed
명령이지만 데모를 위해 약간 정리되고 더 많은 공기를 사용합니다.
sed -i -f - ~/.profile <<'END_SED'
/^#/ b
a \
export PYENV_ROOT="$HOME/.pyenv"\
PATH=$PYENV_ROOT/bin:$PATH
:again
$ ! {
n
b again
}
END_SED
주석이 아닌 첫 번째 줄 바로 뒤에 명령이 삽입 a
되도록 변경합니다.i