처음 x번 발생하면 줄 끝에 텍스트를 추가하려고 합니다. 나는 그것을 전역적으로 수행하는 방법과 n 발생에 대해 알고 있습니다. 처음 n번째 발생에 대해 이를 수행하는 방법을 알 수 없습니다. 다음을 포함하는 text.txt 파일을 예로 들 수 있습니다.
This is a test
junk
This is a test
More junk
This is a test
This is a test
This is a test
그리고 '.'을 추가하고 싶습니다. 처음 세 번이 끝나면 "This is a test"가 발생합니다. 내가 얻으려는 결과는 다음과 같습니다.
This is a test.
junk
This is a test.
More junk
This is a test.
This is a test
This is a test
답변1
This.*test
올바른 정규식입니다. 별표는 "이전 문자의 0배 이상"을 의미하므로 This*test
어떤 줄과도 일치하지 않습니다.
이제 Sed는 산술을 잘 못합니다. 우아한 것을 원한다면 Awk를 제안합니다.
awk '/This.*test/{c++};{print $0 (c<4 ? "." : "")}' file
Awk에서 설정되지 않은 변수는 0으로 처리된다고 말하는 것으로 충분하다고 생각합니다 c
. 그러나 추가 설명이 필요한 경우 알려주십시오.
답변2
3번의 항목이 모두 발견된 후에 정규식 일치를 수행하지 않는 또 다른 변형은 다음과 같습니다.
awk -v n=3 'n && /This is a test/ {n--; $0 = $0 "."}; {print}'
구체적 으로 sed
다음과 같은 작업을 수행할 수 있습니다.
sed '
1 {
x
s/^/.../
x
}
/This is a test/ {
s/$/./
x
s/.//
/./ {
x
b
}
g
:1
$! {
n
b 1
}
}'
여기서 우리는 보유 공간에 .
해당 개수의 s를 추가하기 위해 s 개수를 추적합니다 ..
sed
이런 종류의 작업에는 훨씬 덜 적합하다는 것은 말할 필요도 없습니다 . 원하는 이유가 몇 가지 구현(에서 차용)에서 발견되는 내부 편집 확장 sed
때문 이라면 GNU 구현 도 ¹를 사용하여 수행할 수 있거나 실제를 사용할 수 있다는 점에 유의하십시오.-i
perl
awk
-i /usr/share/awk/inplace.awk
perl -lpi -e '
if ($n < 3 && /This is a test/) {
$n++;
$_ .= ".";
}' your-file
가 하나 이상 포함된 모든 행과 달리 가 발생할 때 .
마다 를 추가하려는 경우 에도 최선의 선택이 될 것입니다.This is a test
This is a test
perl
perl -pi -e 's{This is a test\K}{$n++ < 3 ? "." : ""}ge' your-file
¹사용하지 마세요-i inplace
as 는 누군가 악성 코드를 심었을 수 있는 현재 작업 디렉터리에서 확장명(as 또는 )을 먼저 gawk
로드하려고 시도합니다 . 와 함께 제공되는 확장 프로그램 의 경로는 시스템에 따라 다를 수 있습니다.inplace
inplace
inplace.awk
inplace
gawk
gawk 'BEGIN{print ENVIRON["AWKPATH"]}'
답변3
우리 는 perl
표시된 대로 할 수 있었습니다
perl -lpe '
$_ = $k == 3 ? next : s/This is a test(?{$k++}).*\K/./r;
' file
간단한 스텝에도 불구하고 코끼리도 춤을 출 수 있습니다. GNU sed
확장된 정규식 모드에서 쓰기를 사용하면 -E
보류된 줄 바꿈 수로 개수를 저장할 수 있습니다.
K=3
sed -Ee '
/This is a test/!b
G
/(.*\n){'"$K"'}.*\n/!{
s/\n+/./p;z;H;d
}
s/\n+//
:a;n;ba
' file