입력 파일에서 일부 레코드를 삭제하려고 합니다.
list.txt
tag1,slate1,flag1,status0,8,1
tag2,slate2,flag2,status0,2,3
tag1,slate1,flag1,status1,8,1
tag2,slate2,flag2,status1,2,3
tag1,slate1,flag1,status0,0,1
tag2,slate2,flag2,status1,2,3
tag1,slate1,flag1,status1,1,2
tag2,slate2,flag2,status1,1,2
tag1,slate1,flag1,status1,3,4
예상 출력: list.txt
tag2,slate2,flag2,status0,2,3
tag2,slate2,flag2,status1,2,3
tag1,slate1,flag1,status0,0,1 -> deleted records above this and matching [tag1,slate1,flag1]
tag2,slate2,flag2,status1,2,3
tag1,slate1,flag1,status1,1,2
tag2,slate2,flag2,status1,1,2
tag1,slate1,flag1,status1,3,4
코드를 사용해 봅니다.
sed '/tag2,slate2,flag2,status0/d' list1.txt
하지만 이렇게 하면 tag1,slate1,flag1,status0,0,1, tag1,slate1,flag1,status1,1,2 등의 레코드가 삭제됩니다.
레코드가 'tag1,slate1,flag1,status0,0,1'에 도달하면 sed를 중지할 수 있는 방법이 있나요?
그리고 "tag1,slate1,flag1,status0"이 발견되지 않으면 "tag1,slate1,flag1"과 일치하는 레코드를 삭제할 필요가 없습니다.
출력을 얻기 위한 제안 사항.
답변1
당신은 그것을 사용할 수 있습니다 awk
:
awk '
NR == FNR && /tag1,slate1,flag1,status0/{last_matching=FNR}
NR != FNR && FNR<last_matching && /tag1,slate1,flag1/{next}
NR != FNR
' list.txt list.txt
awk
파일을 두 번 읽습니다.
- 처음 실행할 때(
NR == FNR
)...- 마지막 일치 항목
FNR
(= 파일의 레코드/줄 번호)을 변수에 저장합니다.
- 마지막 일치 항목
- 두 번째 실행에서(
NR != FNR
)...- 일치하는 모든 줄을 건너뜁니다(-->
/tag1,slate1,flag1/{next}
). - 하지만
last_matching
(-->FNR<last_matching
)만 가능합니다. - 를 사용하여 나머지 모든 줄을 인쇄합니다
NR != FNR
.
- 일치하는 모든 줄을 건너뜁니다(-->
답변2
사용sed스트림 편집기 유틸리티를 사용하면 다음을 수행할 수 있습니다.
sed -ne ':top
/^tag1,slate1,flag1,status0,0,1$/!{
/^tag1,slate1,flag1,/!p;n
btop
}
:n;p;n;bn
' list.txt
- 목표 라인을 볼 때까지 일치하지 않는 라인을 계속 인쇄합니다.
- 대상 행이 충족되면 파일이 소진될 때까지 모든 행을 계속 인쇄합니다.