$SOME_TEXT_HERE$
이와 같은 값을 다음과 같은 값 으로 바꾸고 싶습니다 . @some.text.here@
즉:
- 텍스트를 소문자로 변경
$
사용. . . 교체@
- 밑줄을 점으로 바꾸기
초기 문자열에는 관련 없는 텍스트가 얼마든지 있을 수 있습니다. 달러로 구분된 텍스트는 얼마든지 바꿀 수 있습니다. 달러로 구분된 텍스트는 밑줄로 구분된 하나 이상의 대문자로 구성될 수 있습니다.
1단계와 2단계를 수행하는 방법을 알고 있습니다. 3단계를 달러 기호 안에 있는 내용으로 제한하는 방법이 궁금합니다.
좋습니다. 예는 다음과 같습니다.
에서:
Lorem $IPSUM$ $dolor_sit_amet _ _ _ consectetur $ADIPISICING_ELIT$ sed do $EUISMOD_TEMPOR INCIDIDUNT_UT_LABORE$ $ET_DOLORE_MAGNA_ALIQUA$
도착하다:
Lorem @ipsum@ $dolor_sit_amet _ _ _ consectetur @adipisicing.elit@ sed do $EUISMOD_TEMPOR INCIDIDUNT_UT_LABORE$ @et.dolore.magna.aliqua@
나는 이것을 했다:
echo 'Lorem $IPSUM$ $dolor_sit_amet _ _ _ consectetur $ADIPISICING_ELIT$ sed do $EUISMOD_TEMPOR INCIDIDUNT_UT_LABORE$ $ET_DOLORE_MAGNA_ALIQUA$ ' |sed -e 's/\$\([A-Z]\+_\?\)\+\$/\L&/g' -e's/\$\(\([a-z]\+_\?\)\+\)\$/@\1@/g'
이것은 만든다:
Lorem @ipsum@ $dolor_sit_amet _ _ _ consectetur @adipisicing_elit@ sed do $EUISMOD_TEMPOR INCIDIDUNT_UT_LABORE$ @et_dolore_magna_aliqua@
@ 기호 내의 모든 단어를 얻기 위해 일치하는 그룹 결과를 반복하는 방법을 잘 모르겠습니다. 항상 마지막으로 일치하는 결과를 얻습니다.
답변1
펄 사용:
$ cat file
Lorem $IPSUM$ $dolor_sit_amet _ _ _ consectetur $ADIPISICING_ELIT$ sed do $EUISMOD_TEMPOR INCIDIDUNT_UT_LABORE$ $ET_DOLORE_MAGNA_ALIQUA$
$ perl -pe 's/\$([[:upper:]_]+)\$/"@" . lc $1 =~ tr[_][.]r . "@"/eg' file
Lorem @ipsum@ $dolor_sit_amet _ _ _ consectetur @adipisicing.elit@ sed do $EUISMOD_TEMPOR INCIDIDUNT_UT_LABORE$ @et.dolore.magna.aliqua@
여기에 사용된 Perl 표현식은 다음과 같습니다.
s/\$([[:upper:]_]+)\$/"@" . lc $1 =~ tr[_][.]r . "@"/eg
이는 첫 문자 $
, 하나 이상의 대문자 또는 밑줄, 다른 문자로 $
구성된 하위 문자열에 적용되는 대체 입니다.
$1
대체 패턴은 연산자를 사용하여 패턴()의 대괄호 그룹과 일치하는 하위 문자열의 모든 밑줄을 점으로 변경한 tr
다음 결과를 소문자로 변경 하는 Perl 표현식입니다 lc
. 그런 다음 @
결과 앞뒤에 문자를 추가합니다.
이는 Perl이 대체 텍스트를 단순한 텍스트가 아닌 Perl 표현식으로 처리하도록 하는 표현식 /e
플래그 입니다. s///
모든 일치 항목에 대해 교체를 반복하려면 이 플래그를 사용하십시오 /g
.
답변2
$string
입력이 쉘 의 변수 에 저장되면 다음을 zsh
수행할 수 있습니다.
set -o extendedglob
string=${string//(#b)\$([A-Z]##(_[A-Z]##)#)\$/@${(L)match[1]//_/.}@}
perl
같은
string=$(
printf '%s\n' "$string" | perl -pe '
s{\$[A-Z]+(_[A-Z]+)*\$}{lc$& =~ y/_$/.@/r}ge'
)
또는:
string=$(
printf '%s\n' "$string" | perl -pe '
s{\$[A-Z]+(_[A-Z]+)*\$}{$& =~ y/A-Z_$/a-z.@/r}ge'
)
차이점은 로케일에 따라 perl
바이트 수준(ASCII 기반 시스템에서 ASCII 인코딩 필요)과 zsh
문자 수준(문자로 디코딩할 수 없는 경우 바이트로 대체)에서 작동한다는 것입니다. 인코딩을 설정합니다. 개행 문자로 끝나는 경우에도 $string
동작이 달라집니다 . 명령 대체를 통해 해당 문자가 제거되기 때문입니다.
답변3
GNU 사용 sed
: (원하는 대로 sed
)
$ sed -E 's/\$([A-Z]+([A-Z]*_)*[A-Z]+)\$/@\L\1@/g;s/@([a-z]+)_/@\1./g;s/_([a-z]+)@/\.\1@/g; :X s/(\.[a-z]+)_/\1\./g; tX'
산출:
$ echo 'Lorem $IPSUM$ $dolor_sit_amet _ _ _ consectetur $ADIPISICING_ELIT$ sed do $EUISMOD_TEMPOR INCIDIDUNT_UT_LABORE$ $ET_DOLORE_MAGNA_ALIQUA$' | sed -E 's/\$([A-Z]+([A-Z]*_)*[A-Z]+)\$/@\L\1@/g;s/@([a-z]+)_/@\1./g;s/_([a-z]+)@/\.\1@/g; :X s/(\.[a-z]+)_/\1\./g; tX'
Lorem @ipsum@ $dolor_sit_amet _ _ _ consectetur @adipisicing.elit@ sed do $EUISMOD_TEMPOR INCIDIDUNT_UT_LABORE$ @et.dolore.magna.aliqua@
답변4
또 다른 약간 더 짧은 GNUsed
sed -E "s/\\\$([A-Z_]+)\\\$/@\L\1@/g; :X s/(@[a-z.]+)_/\1./; tX" file
이것이 @
소스에서 자연스럽게 발생하지 않고 $
처음에만 발생한다고 가정합니다.[A-Z_]
Lorem $IPSUM$ $dolor_sit_amet _ _ _ consectetur $ADIPISICING_ELIT$ sed do $EUISMOD_TEMPOR INCIDIDUNT_UT_LABORE$ $ET_DOLORE_MAGNA_ALIQUA$
Lorem @ipsum@ $dolor_sit_amet _ _ _ consectetur @adipisicing.elit@ sed do $EUISMOD_TEMPOR INCIDIDUNT_UT_LABORE$ @et.dolore.magna.aliqua@
이는 귀하의 예에서는 잘 작동하지만 대신 $BLAH_BLAH$blah_
->를 사용하면 실패합니다.@blah.blah@blah.
@blah.blah@blah_
편집하다Re @Quasimodo 댓글 +
-> *
두 번째sed
sed -E "s/\\\$([A-Z_]+)\\\$/@\L\1@/g; :X s/(@[a-z.]*)_/\1./; tX" file
Lorem $_IPSUM$ $dolor_sit_amet _ _ _ consectetur $ADIPISICING_ELIT$ sed do $EUISMOD_TEMPOR INCIDIDUNT_UT_LABORE$ $ET_DOLORE_MAGNA_ALIQUA$
Lorem @.ipsum@ $dolor_sit_amet _ _ _ consectetur @adipisicing.elit@ sed do $EUISMOD_TEMPOR INCIDIDUNT_UT_LABORE$ @et.dolore.magna.aliqua@