별도의 줄에서 지정된 일치 횟수 이후의 줄을 AWK로 바꿉니다.

별도의 줄에서 지정된 일치 횟수 이후의 줄을 AWK로 바꿉니다.

현재 저는 AWK를 사용하여 패턴이 처음 세 번 발생한 후 문자열의 일부를 찾아서 교체하고 있습니다. 문자열의 형식은 다음과 같습니다. func(tempID="39849235",count='12');파일에는 아래와 같이 이러한 문자열이 많이 있습니다.

func(tempID="39849235",count='12');
func(tempID="39849235",count='12');
func(tempID="39849235",count='12');
func(tempID="39849235",count='12');
func(tempID="39849235",count='12');
func(tempID="39849235",count='12');

사용이 링크, AWK를 사용하여 문자열의 처음 세 인스턴스를 찾아 바꾸는 방법을 찾을 수 있었습니다. 나는 그것을 내가 필요로 하는 것으로 변경했고, 내 스크립트의 일부는 아래와 같습니다:

id=12349876
awk -v id="$id" 'BEGIN {matches=0}
     matches < 3 && /.*tempID.*/ { sub(/tempID=.[0-9]+./,"tempID=\""id"\""); matches++ }
     { print $0 }' filName.py >filName.py.changed

위 코드의 목표는 tempID가 포함된 모든 행을 일치시키고 tempID에 할당된 숫자를 이름이 지정된 변수에 포함된 값으로 바꾸는 것입니다 $id. 찾기 및 바꾸기는 잘 작동하지만 이제 인스턴스 4-9를 다른 번호로 바꾸고 싶습니다. 다음 방법을 시도했지만 여전히 tempID의 처음 5개 인스턴스만 대체되었습니다.

id2=39843237
awk -v id2="$id2" 'BEGIN {matches=4}
     matches < 9 && /.*tempID.*/ { sub(/tempID=.[0-9]+./,"tempID=\""id2"\""); matches++ }
     { print $0 }' filName.py >filName.py.changed

해당 값 범위가 대체되도록 이를 구현하는 다른 방법이 있습니까? AWK를 사용할 필요는 없으며 sed 또는 기타 Linux 유틸리티를 사용할 수 있습니다. 게다가 솔루션이 꼭 특정 지점에서 끝날 필요는 없고 세 번째 줄 이후의 모든 인스턴스를 교체하는 것도 허용되는데, 이렇게 할 수 있는 솔루션이 있다면 플러스가 될 것이다.

답변1

귀하의 matches=4의미 matches < 9는 "이미 4개의 일치 항목이 있다고 가정하고 총 9개가 될 때까지 행동합니다"를 의미합니다. 이것이 처음 5개의 인스턴스가 교체되는 이유입니다. 이전과 같이 양식 0을 시작한 다음 논리에 하한을 포함해야 합니다.

id2=39843237
awk -v id2="$id2" 'BEGIN {matches=0}
 matches >=3 && matches < 9 && /.*tempID.*/ { sub(/tempID=.[0-9]+./,"tempID=\""id2"\"") }
 /.*tempID.*/ { matches++ }
 { print $0 }' filName.py >filName.py.changed

값에 따라 교체를 수행해야 matches하지만 일치하는 항목이 발생할 때마다 이 값을 늘려야 합니다. 원본 코드가 텍스트를 대체하고 한 블록의 값을 늘렸습니다. 너무 높아 대체품이 없을 때는 matches값이 더 이상 늘어나지 않았지만 더 이상 문제가 되지 않았습니다. 이제 이 간단한 접근 방식으로는 벗어날 수 없습니다. matches불량 으로 인한 교체가 없을 때너무 낮은, 일치하는 문자열이 발견되면 값을 늘려야 합니다.

따라서 두 {}블록은 별도의 조건을 갖습니다.

관련 정보