Sed: N개의 문자를 대체합니다.

Sed: N개의 문자를 대체합니다.

sed 스크립트의 각 줄에서 처음 5개의 공백 문자를 바꾸고 싶습니다. 이것이 내가 지금까지 가지고 있는 것입니다

sed -e "s/ /;/" -e "s/ /;/" -e "s/ /;/" -e "s/ /;/" -e "s/ /;/" myfile

더 좋은 방법이 있나요?

그런데 저는 Solaris sed를 사용하고 있습니다. 그것이 차이를 가져오는지는 모르겠습니다.

답변1

귀하의 질문을 읽으면서 적어도 GNU Sed(아마도 Solaris에 있는 것이 아닐 수도 있음)가원하는 반대 기능:

g: 첫 번째 항목뿐만 아니라 정규식과 일치하는 모든 항목에 대체를 적용합니다.

number: 정규 표현식의 숫자 번째 일치 항목만 바꿉니다.

Note: the posix standard does not specify what should happen when

현재 sed 구현 간에 널리 합의된 의미가 없는 g 및 숫자 수정자를 혼합하고 있습니다. GNU sed의 경우 상호 작용은 다음과 같이 정의됩니다. 세 번째 일치 이전의 일치 항목을 무시한 다음 세 번째 일치 이후의 모든 일치 항목을 일치시키고 교체합니다.

그래서 대신:

hmontoliu@ulises:/tmp/wb$ echo one two three four five six seven | sed 's/ /;/g5' 
one two three four five;six;seven

다음을 수행하여 원하는 것을 달성하기 위한 보다 간결한 명령을 얻을 수 있습니다.

hmontoliu@ulises:/tmp/wb$ echo one two three four five six seven | sed -e 's/ /;/g' -e 's/;/ /6g'
one;two;three;four;five;six seven

Solaris 구현에 이 기능이 있는지 알려주십시오.

화타이

답변2

반복적인 sed 저글링을 수행하는 것보다 기본 아이디어를 고수하는 것이 더 쉽습니다. 아마도 간단한 for 루프를 사용하여 패턴을 구축하면 사용하기가 더 쉬워질 것입니다.

pat=; for ((i=1; i<=5; i++)) ;do pat="$pat s/ /;/;"; done
sed -e "$pat" myfile

아니면 여러 -e표현식 옵션을 삭제하고 ;표현식 구분 기호로 모두 그룹화하면 됩니다.

sed -e "s/ /;/; s/ /;/; s/ /;/; s/ /;/; s/ /;/" myfile

이건 sed-오직일반적으로 귀찮게 하지 않을 버전이지만 대체 항목을 원하는 만큼 지정할 수 있습니다. (통과하다 {5})...

sed -nre ':check;G;/^.*\nx{5}$/{b print};s/^(.*)\n.*$/\1/;s/ /;/;t inc-tally;:print;P;x;s/.*//;x;b;:inc-tally;x;s/(.*)/\1x/;x;b check' myfile

~ 위에한 줄(?)조금 무섭기 때문에 여기에 sed 스크립트 파일을 통해 호출되는 구조화된 코드가 있습니다.sed -nrf "$fsed" myfile

:check             ## check the tally
 G                 ## pattern+=nl+hold
 /^.*\nx{5}$/{     ## we have the full complement of replacements
     b print       ## branch to print (and continue)
 }                 ##      
 s/^(.*)\n.*$/\1/  ##
 s/ /;/            ## change one space (if one is present) 
 t inc-tally       ## branch_on_substitute
:print             ## no more spaces to change
 P                 ## pattern_first_line_print
 x;s/.*//;x        ## kill the accumulated tally chars in hold   
 b                 ## branch to end of proc (continue)
:inc-tally         ##      
 x                 ## swap_pattern_and_hold
 s/(.*)/\1x/       ##
 x                 ## swap_pattern_and_hold
 b check           ## branch_unconditional 

관련 정보