실행할 기본 명령 대신 "명령 매크로"가 사용되는 코드 조각을 상속받았습니다 . $TR
예를 들어 명령 매크로를 참조하는 셸 명령으로 다시 변환하는 tr
데 사용하고 싶습니다 . sed
문제는 단어 경계에 있습니다.
$ echo '$TR $TRUE $TRUNCATE "$TR ($TR' | sed s/\$TR/tr/g
tr trUE trUNCATE "tr (tr
분명히 잘못된 것입니다. 그러나 다음을 \b
사용하여 번역된 단어 경계를 설정하려고 하면 작동하지 않습니다.
$ echo '$TR $TRUE $TRUNCATE "$TR ($TR' | sed s/\$TR\b/tr/g
$TR $TRUE $TRUNCATE "$TR ($TR
매크로 길이를 역순으로 검색하는 것(즉 $TRUNCATE
, 먼저 교체 $TRUE
, 다음 교체)은 독립적인 콘텐츠만 으로 변환되는 $TR
경우도 있으므로 완전한 솔루션은 아닙니다 .$TS $TS_FORMAT
$TS
ts
\b
여기서 단어 경계 태그가 작동하지 않는 이유가 있나요? 이 문제를 해결하려면 어떻게 해야 합니까?
$ sed --version
sed (GNU sed) 4.7
Packaged by Debian
Copyright (C) 2018 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Written by Jay Fenlason, Tom Lord, Ken Pizzini,
Paolo Bonzini, Jim Meyering, and Assaf Gordon.
GNU sed home page: <https://www.gnu.org/software/sed/>.
General help using GNU software: <https://www.gnu.org/gethelp/>.
E-mail bug reports to: <[email protected]>.
편집하다
명령 매크로를 정의하는 파일에는 FQFN이 부적절하더라도(예: while return $TRUE
으로 정의됨 ) 대체된 모든 명령의 정규화된 파일 이름이 포함됩니다. 이로 인해 참조 시 디스크의 파일이 실행되므로 명령 매크로(이 경우)를 사용하면 성능에 상당한 영향을 미칠 수 있습니다./usr/bin/true
type true
true is a shell builtin
$TRUE
목표는 명령 매크로가 source
정의된 d 파일에서 사라지고 제거될 수 있도록 코드 베이스의 파일을 업데이트하여 향후 코드 독자와 유지관리자가 명령 매크로를 전혀 다룰 필요가 없도록 하는 것입니다.
답변1
sed 표현식은 인용되지 않았으므로 쉘은 이를 \b
일반으로 변환할 수 있습니다 b
. 예를 들어 Bash에서는 다음과 같습니다.
set -x
$ echo '$TR $TRUE $TRUNCATE "$TR ($TR' | sed s/\$TR\b/tr/g
+ sed 's/$TRb/tr/g'
+ echo '$TR $TRUE $TRUNCATE "$TR ($TR'
$TR $TRUE $TRUNCATE "$TR ($TR
하지만
$ echo '$TR $TRUE $TRUNCATE "$TR ($TR' | sed 's/\$TR\b/tr/g'
+ sed 's/\$TR\b/tr/g'
+ echo '$TR $TRUE $TRUNCATE "$TR ($TR'
tr $TRUE $TRUNCATE "tr (tr
그러나 sed가 작업에 적합한지 의문이 듭니다. 아마도 envsubst
ex와 같은 것을 고려해 볼 수도 있습니다.
$ echo '$TR $TRUE $TRUNCATE "$TR ($TR' | env TR=tr TRUE=true TRUNCATE=truncate envsubst
tr true truncate "tr (tr
답변2
휴대용 솔루션의 경우 다음을 사용할 수 있습니다 perl
(GNU가 sed
복사된 위치 \b
).
perl -pe 's/\$(?|(TR|TRUE|TRUNCATE|TS)\b|\{((?1))\})/\L$1/g'
대체 후의 소문자 내용은 실제로 / \L
에서 나옵니다 . GNU 구현에서도 사용할 수 있지만 다른 구현에서는 표준이 아니거나 이식 가능하지 않습니다.ex
vi
sed
sed
(?1)
(TR|TRUE|TRUNCATE|TS)
첫 번째 대괄호 쌍에 포함된 정규식을 호출하고 여기서 사용하면 변형과 일치하기 위해 교대로 반복할 필요가 없습니다${VAR}
.(?|...)
~이다분기 재설정.(?:...)
주요 차이점은(a(x)|b(y))
end up, by in 및 in과 일치하는 내용이 ->, ->,x
$2
y
$3
(...)
$1
(?:a(x)|b(y))
x
$1
y
$2
(?:...)
그룹하지만포착, 및 에서는(?|a(x)|b(y))
와 일치하거나 로 끝나는 콘텐츠입니다.x
y
$1
GNU를 사용하면 sed
다음을 수행할 수 있습니다.
vars='(TR|TRUE|TRUNCATE|TS)'
sed -E "s/\\\$($vars\>|\{$vars\})/\L\2\3/g"
\>
(또한 ex
/ )는 다른 사전주의와 일관성을 유지하기 위해 여기에서 vi
Perl 스타일 대신 사용되었지만 여기서의 작동 원리는 동일합니다.\b
\L
\b