파일에서 N번째 패턴만 바꾸는 방법은 무엇입니까?

파일에서 N번째 패턴만 바꾸는 방법은 무엇입니까?

어떻게 교체할 수 있나요?질소파일에서 문자열(또는 패턴)이 세 번째(예: 세 번째) 발생하도록 명령을 사용합니까  sed? 내 말은질소대신 파일에서 처음으로 나타나는질소한 줄의 두 번째 발생 또는 한 줄의 첫 번째 발생 질소일치하는 라인. 한 줄에 여러 번 나타날 수 있으며 발생(일치)은 단어의 일부일 수 있습니다.

예:

is파일에서 세 번째로 나타나는 to만 변경됩니다.us

내 입력 파일에는 다음이 포함됩니다.

hai this is linux.
hai this is unix.
hai this is mac.
hai this is unchanged.

예상되는 출력은 다음과 같습니다.

hai this is linux.
hai thus is unix.
hai this is mac.
hai this is unchanged.

"this"가 "th"로 대체되었습니다.우리를"두 번째 줄에.

답변1

완료하는 데 사용하는 것이 훨씬 쉽습니다 perl.

세 번째 발생 위치를 변경하려면 다음을 수행하십시오 .

perl -pe 's{is}{++$n == 3 ? "us" : $&}ge'

3번마다 변경하세요 .

perl -pe 's{is}{++$n % 3 ? $& : "us"}ge'

답변2

sed이전 개행 문자가 다른 문자로 대체되는 경우 이를 사용할 수 있습니다. 예를 들면 다음과 같습니다.

tr '\n' '\000' | sed 's/is/us/3' | tr '\000' '\n'

순수(GNU)와 동일 sed:

sed ':a;N;$!ba;s/\n/\x0/g;s/is/us/3;s/\x0/\n/g'

( sed뻔뻔스럽게 개행 교체https://stackoverflow.com/a/1252191/4488514)

답변3

대체 문자열이 한 줄에 한 번만 나타나는 경우 다양한 유틸리티를 결합할 수 있습니다.
입력이 "input" 파일에 있고 "is"를 "us"로 바꾸면 다음을 사용할 수 있습니다.

LINENR=$(cat input | grep -n " is " | head -3 | tail -1 | cut -d: -f1)
cat input | sed ${LINENR}' s/ is / us /'

답변4

p='[:punct:]' s='[:space:]'
sed -Ee'1!{/\n/!b' -e\}            \
     -e's/(\n*)(.*)/ \2 \1/'       \
     -e"s/is[$p]?[$s]/\n&/g"       \
     -e"s/([^$s])\n/\1/g;1G"       \
-e:c -e"s/\ni(.* )\n{3}/u\1/"      \
     -e"/\n$/!s/\n//g;/\ni/G"      \
     -e's//i/;//tc'                \
     -e's/^ (.*) /\1/;P;$d;N;D'

이 비트에는 한 줄에서 다음 줄까지의 발생 횟수 sed만 포함됩니다 . 한 줄에 가능한 is한 많은 es를 안정적으로 처리해야 하며 is오래된 줄을 버퍼링할 필요가 없습니다. is다른 단어에 속하지 않는 각 부분에 대해 개행을 예약할 뿐입니다.

결과적으로 파일에서 세 번째 항목만 수정되며 각 줄에는 개수가 포함됩니다. 따라서 파일이 다음과 같은 경우:

1. is is isis
2. is does

...인쇄됩니다...

1. is is isis
2. us does

먼저 각 줄의 시작과 끝 부분에 공백을 삽입하여 극단적인 경우를 처리합니다. 이렇게 하면 단어 경계를 더 쉽게 결정할 수 있습니다.

다음으로, 0개 또는 1개의 구두점 문자(뒤에 공백이 옴) 바로 뒤에 나오는 모든 es 앞에 ewline을 삽입하여 유효한 es를 찾습니다 is. 또 다른 패스를 수행하고 공백이 아닌 문자 뒤에 오는 모든 줄 바꿈을 제거합니다. 나머지 토큰은 and와 일치하지만 or는 일치하지 않습니다.\nis\nis.isthis?is

다음으로, 각 토큰을 문자열 끝까지 수집합니다. \ni행의 각 일치 항목 에 대해 \n문자열 끝에 ewline을 추가하고 이를 ior 로 바꿉니다 u. \n문자열 끝에 3개의 연속된 ewline이 클러스터되어 있으면 u를 사용하고, 그렇지 않으면 i를 사용합니다 . 내가 au를 처음 사용한 것은 마지막 때이기도 했습니다. 대체 작업으로 인해 무한 루프가 발생하여 계속해서 이어졌습니다 get line, print line, get line, print line,.

각 try 루프 주기가 끝나면 삽입된 공백을 지우고 패턴 공간에서 처음 나타나는 개행 문자만 인쇄한 다음 다시 실행합니다.

l루프 시작 부분에 ook 명령을 추가합니다. 예를 들면 다음과 같습니다.

l; s/\ni(.* )\n{9}/u\1/...

...이 입력을 처리할 때 수행되는 작업을 확인하세요.

hai this is linux.
hai this is unix.


hai this is mac.
hai this is unchanged is.

...그래서 이것이 하는 일입니다:

 hai this \nis linux. \n$        #behind the scenes
hai this is linux.               #actually printed
 hai this \nis unix. \n\n$       #it builds the marker string
hai this is unix.
  \n\n\n$                        #only for lines matching the

  \n\n\n$                        #pattern - and not otherwise.

 hai this \nis mac. \n\n\n$      #here's the match - 3 ises so far in file.
hai this us mac.                 #printed
hai this is unchanged is.        #no look here - this line is never evaled

is한 줄에 더 많은 es를 갖는 것이 더 합리적일 수 있습니다.

nthword()(  p='[:punct:]' s='[:space:]'         
    sed -e '1!{/\n/!b' -e\}             \
        -e 's/\(\n*\)\(.*\)/ \2 \1/'    \
        -e "s/$1[$p]\{0,1\}[$s]/\n&/g"  \
        -e "s/\([^$s]\)\n/\1/g;1G;:c"   \
        -e "${dbg+l;}s/\n$1\(.* \)\n\{$3\}/$2\1/" \
        -e '/\n$/!s/\n//g;/\n'"$1/G"    \
        -e "s//$1/;//tc" -e 's/^ \(.*\) /\1/'     \
        -e 'P;$d;N;D'
)        

이는 본질적으로 동일하지만 POSIX BRE 및 기본 매개변수 처리로 작성되었습니다.

 printf 'is is. is? this is%.0s\n' {1..4}  | nthword is us 12

...얻다...

is is. is? this is
is is. is? this is
is is. is? this us
is is. is? this is

...활성화하는 경우 ${dbg}:

printf 'is is. is? this is%.0s\n' {1..4}  | 
dbg=1 nthword is us 12

...우리는 그것이 반복되는 것을 볼 수 있습니다...

 \nis \nis. \nis? this \nis \n$
 is \nis. \nis? this \nis \n\n$
 is is. \nis? this \nis \n\n\n$
 is is. is? this \nis \n\n\n\n$
is is. is? this is
 \nis \nis. \nis? this \nis \n\n\n\n\n$
 is \nis. \nis? this \nis \n\n\n\n\n\n$
 is is. \nis? this \nis \n\n\n\n\n\n\n$
 is is. is? this \nis \n\n\n\n\n\n\n\n$
is is. is? this is
 \nis \nis. \nis? this \nis \n\n\n\n\n\n\n\n\n$
 is \nis. \nis? this \nis \n\n\n\n\n\n\n\n\n\n$
 is is. \nis? this \nis \n\n\n\n\n\n\n\n\n\n\n$
 is is. is? this \nis \n\n\n\n\n\n\n\n\n\n\n\n$
is is. is? this us
is is. is? this is

관련 정보