이전 질문을 검색했는데 질문이 나온 후에 추가되었습니다. 전에 필요해요:
world world
world world
world world
따라서 sed는 특정 텍스트의 N번째 발생 시작 부분에 "hello"를 추가해야 합니다. 이 경우에는 네 번째 세계에 다음을 추가합니다.
world world
world hello world
world world
답변1
반드시 sed를 사용해야 한다면 다음을 시도해 볼 수 있지만 이미 설명에서 알 수 있듯이 sed 경로는 불안정할 것입니다.
sed -e '
H;1h;g
s/world/HELLO &/4;tn
$!d;:n;n;bn
' yourfile
답변2
sed
작업에 잘못된 도구입니다. 사용 awk
하거나 perl
대체하십시오. 예를 들어
$ perl -pe 's/world/++$i == 4 ? "hello world" : $&/ge' input.txt
world world
world hello world
world world
이는 /e
대체 연산자의 대체 부분이 s///
문자열로 해석되지 않고 Perl 코드로 실행되도록 하는 perl regex 수정자를 사용한다는 점에 유의하십시오.
코드는 각 일치 항목에 대해 ++$i == 4 ? "hello world" : $&
카운터 변수( )를 미리 증가시키고 $i
, 4와 같으면 일치 항목을 "hello world"로 바꾸고, 그렇지 않으면 일치 항목을 자체 항목( $&
)으로 바꿉니다.
답변3
"sed를 사용하세요"라고 말씀하신 건 알지만, 현실 세계에서 이와 같은 작업을 수행해야 한다면 모든 Unix 시스템의 모든 쉘에서 awk를 사용하고 전체 단어 문자열 비교를 수행하는 방법은 다음과 같습니다(참조패턴과 일치하는 텍스트를 찾는 방법이것이 중요한 이유):
$ awk -v n=4 '{
for (i=1;i<=NF;i++) {
if ( ($i == "world") && (++cnt == n) ) {
$i = "hello " $i
}
}
print
}' file
world world
world hello world
world world
입력 내용이 다음과 같다고 상상해 보세요.
$ cat file
google.com mygoole.comedy
googleycom google.com
google.com google.com
google.com
그리고 네 번째 항목 (현재 입력의 마지막 항목) 앞에 "hello"를 넣으려고 합니다 . 위의 awk 스크립트를 사용하면 다음과 같이 변경 $i=="world"
됩니다 $i=="google.com"
.
$ cat file
awk -v n=4 '{
for (i=1;i<=NF;i++) {
if ( ($i == "google.com") && (++cnt == n) ) {
$i = "hello " $i
}
}
print
}' file
google.com mygoole.comedy
googleycom google.com
google.com hello google.com
이제 sed 스크립트를 사용하여 동일한 작업을 수행해 보십시오(특히 POSIX 구문만 사용하고 GNU 확장을 사용하지 않는 경우). 이제 sed 스크립트를 in&out
대체 텍스트로 사용해 보면 더 많은 문제를 발견하게 될 것입니다.hello
답변4
sed 'H;1h;$!d;x;s/world/hello &/4'