${VAR//search/replace} 매개변수 확장을 사용하여 변수에 대한 일부 검색 및 바꾸기를 수행하려고 합니다. 나는 길고 사악한 PS1을 가지고 있는데 확장하면 얼마나 커질지 알고 싶습니다. 이렇게 하려면 여기에 포함된 여러 이스케이프 시퀀스를 제거해야 했습니다. 그러나 모든 ANSI CSI SGR 시퀀스를 제거하려고 할 때 구문 문제가 발생했습니다.
내 PS1을 고려하면:
PS1=\[\033]0;[\h] \w\007\]\[\033[1m\]\[\033[37m\](\[\033[m\]\[\033[35m\]\u@\[\033[m
\]\[\033[32m\]\h\[\033[1m\]\[\033[37m\]\[\033[1m\])\[\033[m\]-\[\033[1m\](\[\033[m
\]\t\[\033[37m\]\[\033[1m\])\[\033[m\]-\[\033[1m\](\[\033[m\]\[\033[36m\]\w\[\033[1m
\]\[\033[37m\])\[\033[35m\]${git_branch}\[\033[m\]\n$
(네, 아픈 건 알아요...)
나는하려고합니다 :
# readability
search='\\\[\\033\[[0-9]*m\\\]'
# do the magic
sane="${PS1//$search/}"
그러나 이들은 욕심이 많은 것 같습니다 [0-9]
(거의 반대 [0-9]
라고 간주되는 것과 같습니다)..
echo "${PS1//$search/}"
\[\033]0;[\h] \w\007\]\n$
을 제거하고 (이것이 더 설명적이므로) 로 *
변경 하면 예상된 결과에 더 가까워집니다.[0-9]
[0-9][0-9]
$ search='\\\[\\033\[[0-9][0-9]m\\\]'
$ echo "${PS1//$search/}"
\[\033]0;[\h] \w\007\]\[\033[1m\](\[\033[m\]\u@\[\033[m\]\h\[\033[1m
\]\[\033[1m\])\[\033[m\]-\[\033[1m\](\[\033[m\]\t\[\033[1m\])\[\033[m\]-\[\033[1m
\](\[\033[m\]\w\[\033[1m\])$(git_branch)\[\033[m\]\n$
왜 *
(0개 이상) 미친 짓을 할까요? 여기서 뭔가 빠졌나요? sed를 통해 동일한 정규식을 전달하면 예상되는 결과를 얻습니다.
echo $PS1 | sed "s/$search//g"
\[\033]0;[\h] \w\007\](\u@\h)-(\t)-(\w)$(git_branch)\n$
답변1
\[
와 사이의 항목을 제거하려는 것 같습니다 \]
.
$ shopt -s extglob
$ printf '%s\n' "${PS1//\\\[*(\\[^]]|[^\\])\\\]/}"
(\u@\h)-(\t)-(\w)${git_branch}\n$
그러나 대체는 매우 비효율적이므로 bash
여기에서 perl
OR을 실행 sed
하거나 다음과 같이 루프에서 수행하는 것이 더 나을 것입니다.
p=$PS1 np=
while :; do
case $p in
(*\\\[*\\\]*) np=$np${p%%\\\[*};p=${p#*\\\]};;
(*) break;;
esac
done
np=$np$p
printf '%s\n' "$np"
(그런데 이것은 위의 표준 POSIX sh 구문입니다.)
네가 원한다면확장하다힌트:
ep=$(PS4=$np;exec 2>&1;set -x;:); ep=${ep%:}
답변2
jordanm의 안내를 받은 후(그리고 bash 매뉴얼 페이지의 "패턴 일치" 섹션을 읽은 후) 매개변수 확장에 사용되는 이러한 패턴은 정규식이 아니라는 것이 밝혀졌습니다. 하지만 내 특별한 경우에 shopt extglob
켜져 있으면 다음과 같이 할 수 있습니다.
search='\\\[\\033\[*([0-9])m\\\]'
*([0-9])
여기서는 정규식과 동일 합니다 [0-9]*
.
extglob은 bash 매뉴얼 페이지에서 정규식과 유사한 메커니즘을 제공하는 것 같습니다.
?(pattern-list)
Matches zero or one occurrence of the given patterns
*(pattern-list)
Matches zero or more occurrences of the given patterns
+(pattern-list)
Matches one or more occurrences of the given patterns
@(pattern-list)
Matches one of the given patterns
!(pattern-list)
Matches anything except one of the given patterns
답변3
Pure Bash 전체 범위의 ANSI 시퀀스 지원
# Strips ANSI CSI (ECMA-48, ISO 6429) codes from text
# Param:
# 1: The text
# Return:
# &1: The ANSI stripped text
strip_ansi() {
shopt -s extglob
printf %s "${1//$'\e'[@A-Z\[\\\]\^_]*([0-9:;<=>?])*([ \!\"#$%&\'()\^*+,\-.\/])[@A-Z\[\\\]\^_\`a-z\{|\}~]/}"
}