sed를 사용하여 n번째 발생 후 검사를 추가하고 싶습니다.
입력하다:
DCR
DCR
DCR
산출:
DCR
DCR
check
DCR
sed를 사용할 수 있나요?
답변1
GNU sed를 사용하면 대체할 수 있습니다.Na의 번째 패턴철사
$ echo "foofoofoofoo" | sed 's/foo/&\nbar/2'
foofoo
barfoofoo
이 아니라면N패턴을 포함하는 3행은 awk를 사용하면 더 쉽습니다.
awk -v n=2 -v patt=foo '{print} $0 ~ patt && ++count == n {print "bar"}' <<END
foo1
foo2
foo3
foo4
END
foo1
foo2
bar
foo3
foo4
답변2
GNU sed 사용:
sed -z 's/DCR/&\ncheck/2' <input >output
업데이트되지 않은 버전의 경우:
sed '/DCR/{p;s/.*/1/;H;g;/^\(\n1\)\{2\}$/s//check/p;d}' <input >output
DCR
연속해서 1회 이상 발생하는 경우:
sed '
/DCR/{p
x # tests if already have met pattern
/^\(\n\a\)\{2\}/!{ #+apropriate times and, if so, cancel
x #+the rest of commands
s/DCR/\a/g # exchange DCR by \a symbol
s/^[^\a]*\|[^\a]*$//g # delete everything before & after it
s/[^\a]\+/\n/g # substitute everything between by \n
H
g
/^\(\n\a\)\{2\}/s/.*/check/p} # add 'check' for double pattern
d}' <input >output
답변3
sed
스택에서 할 수 있습니다 ...
sed '/match$/N
s/\n/&INSERT&/3;t
$n;N;P;D'
그러면 삽입됩니다INSERT
3시마다비순차적일어난match
입력 중. 이것은 sed
서로 다른 모든 행을 저장하려고 시도하지 않기 때문에 내가 아는 가장 효율적인 방법입니다.matches
, 또한 버퍼 교환이나 역참조 비교가 필요하지 않지만 sed
단순히 줄 번호를 줄 기간만큼 늘리는 유일한 계산 방법입니다.
물론 이로 인해 약간의 오버헤드가 추가됩니다. 즉, 일치하는 각 패턴 공간이 약간 더 커지지만 여전히 동일한 스트림이고 역추적은 없습니다. 오직선입선출- 매우 적절한 접근 방식이라고 생각합니다 sed
. 실제로 돌아가서 일치 항목을 확인하는 대신 다음을 sed
수행할 수 있습니다 .더 나아가모든 게임. 조금 자랑스럽습니다. 왜 전에는 그런 생각을 한 번도 해본 적이 없는지 모르겠습니다.
그러나 위 버전은 입력 후 한 줄만 작동하기 때문에 반복을 다소 압축합니다. 해결책은 한 단계 더 나아가 전류 흐름을 유지하기 위해 루프 내부에 b
목장 :l
아벨 단락 회로 루프를 설정하는 약간의 추가 복잡성이 필요한 것입니다 .N;P;D
작동 방식은 다음과 같습니다.
seq 100000| sed -ne':n
s/\n/&\tCheck&\t/5p;t
N;/0000$/bn' -eD
...나에게는 인쇄가...
49995
49996
49997
49998
49999
Check
50000
99995
99996
99997
99998
99999
Check
100000
카운트를 유지하기 위해 발생할 때마다 라인 버퍼를 늘립니다.match
그리고 패턴 공간의 슬라이딩 창에 또 다른 선을 고정합니다. 이렇게 하면 일치 항목이 발견되었는지 확인하는 데 필요한 모든 작업은 교체를 시도하는 것입니다.s///
nth
\n
패턴 공간의 줄 문자. 혹시라도 우리는 만났나요n matches
지금까지 t
est는 현재 반복에서 분기하여 증분을 완전히 지울 수 있습니다.
위의 예에서 버퍼는 문자열로 끝나는 각 패턴 공간에 대해 한 번씩 증가합니다.0000
. 그 중 5개가 발견되면 sed
현재 패턴 공간과 전체 버퍼를 인쇄하고 카운터를 지웁니다.
당신을 위해:
printf DCR\\n| tee - - - - - |
sed -e:n -e's/\n/&\tCheck&\t/2;t
$n; N;/DCR$/bn' -eP\;D
DCR
DCR
Check
DCR
DCR
DCR
Check
DCR
이제 표시하고 싶다면오직이것nth
그것은 매우 간단합니다.
printf DCR\\n |
tee - - - - - - - - -|
sed -e:n -e's/\n/&\tCheck&\t/3;te
$n; N;/DCR$/bn' -e'P;D;:e
n;be'
...자세히 살펴보면 표면만 긁었을 뿐이라는 것을 알 수 있습니다...
DCR
DCR
DCR
Check
DCR
DCR
DCR
DCR
DCR
DCR
DCR
답변4
GNU sed
sed
작업에 적합하지는 않지만 물론 여전히 할 수 있습니다. 다음은 매우 긴 문자열을 예약된 공간에 저장하고 이를 사용하여 발생 횟수를 n
계산하는 방법 입니다.DCR
n=2
((yes | head -n$n | tr -d \\n; echo); cat infile) |
sed '
1 {h;d} # save counting string
/DCR/ { #
x; s/.//; x # n--
T chk # if n=0 goto "chk"
}
P;D
:chk # insert check
i\check
:a; N; ba # print rest of file
'
앗
지적한대로글렌, awk가 더 깨끗합니다. 여기에 골프 버전이 있지만 비슷한 논리가 있습니다.
<infile awk '!n { print "check" } /DCR/ { n-- } 1' n=2