정규식을 사용하여 목록에서 특정 반복 문자를 제거할 수 있습니까?

정규식을 사용하여 목록에서 특정 반복 문자를 제거할 수 있습니까?

약 100개의 행이 포함된 열 목록이 있는데 그 중 일부는 중복되어 있습니다. 내 의도는 제거하는 것입니다.특정한행을 복제하고만 유지하나복사되지만 다른 행은 변경되지 않습니다.

내가 작업 중인 파일에서 발췌:

V(Mn9)   
V(C1,H3) 
V(Mn6)   
V(Mn6)   
V(C4,H6) 
V(Mn9)   
V(Mn9)   
V(C1,Mn6)
V(C4,Mn9)
V(Mn6)   
V(C1,C4) 
C(Mn9)   
C(Mn6)   
C(C1)    
C(C4)    
C(Mn9)   
C(Mn6)   
V(C1,H2) 
V(Mn9)   
V(Mn6)   
V(C4,H5)

내 목적은 C(Xx0-9)를 포함하는 모든 중복 행을 제거하고 그 중 하나를 유지하고 V(Xxx..)를 유지하는 것입니다.

내가 찾고 있는 결과:

V(Mn9)   
V(C1,H3) 
V(Mn6)   
V(Mn6)   
V(C4,H6) 
V(Mn9)   
V(Mn9)   
V(C1,Mn6)
V(C4,Mn9)
V(Mn6)   
V(C1,C4) 
C(C1)    
C(C4)    
C(Mn9)   
C(Mn6)   
V(C1,H2) 
V(Mn9)   
V(Mn6)   
V(C4,H5)

나는 다음 명령을 사용했습니다.

sed '0,/C(Mn9)/{/C(Mn9)/d}' inputfile.txt | sed '0,/C(Mn6)/{/C(Mn6)/d}'

작동하지만 C(Xx1-50)가 많고 정규식을 사용하고 싶지만 방법을 모르기 때문에 전체 파일에 충분하지 않습니다. 그래서 여러분의 도움이 필요합니다.

답변1

$ awk '!(/^C\(..[0-9])$/ && seen[$0]++)' file
V(Mn9)
V(C1,H3)
V(Mn6)
V(Mn6)
V(C4,H6)
V(Mn9)
V(Mn9)
V(C1,Mn6)
V(C4,Mn9)
V(Mn6)
V(C1,C4)
C(Mn9)
C(Mn6)
C(C1)
C(C4)
V(C1,H2)
V(Mn9)
V(Mn6)
V(C4,H5)

위의 내용은 예제 입력에서 표시되는 문자 앞/뒤에 공백이 없다고 가정합니다. 그렇다면 다음과 같이 삭제하세요.

$ awk '{gsub(/^[[:space:]]+|[[:space:]]+$/,"")} !(/^C\(..[0-9])$/ && seen[$0]++)' file
V(Mn9)
V(C1,H3)
V(Mn6)
V(Mn6)
V(C4,H6)
V(Mn9)
V(Mn9)
V(C1,Mn6)
V(C4,Mn9)
V(Mn6)
V(C1,C4)
C(Mn9)
C(Mn6)
C(C1)
C(C4)
V(C1,H2)
V(Mn9)
V(Mn6)
V(C4,H5)

답변2

sed이전에 나타난 적이 있는지 확인하려면 예약된 공간의 수집 행을 사용하는 것이 좋습니다 .

 sed -n 'H;G;/^\(C([^)]*)\).*\1 *\n/!P'
  • H현재 행을 예약된 공간에 추가
  • G우리가 본 모든 라인이 있는 패턴 공간에 예약된 공간을 추가합니다.
  • C([^)]*)는 줄의 시작 부분에 고정하는 C(…)패턴 중 하나이며 나중에 다시 참조 할 수 있도록 둘러싸여 있습니다. 끝에 새로 추가된 줄과 일치하는 것을 피하기 위해 개행(가능한 공백 뒤에)이 있는 패턴이 필요합니다 . 따라서 전체 패턴은 중복 항목이 있는 행과 일치하므로 이것이 일치하지 않는 경우에만^\(…\)\1\1 *\n/^\(C([^)]*)\).*\1 *\n/C(…)!
  • P-n첫 번째 개행 이전의 모든 내용을 인쇄합니다(= 추가 예약 공간 없음). 반면 이 옵션은 기본 출력을 억제합니다.

버전과 파일 크기 에 따라 sed시간이 지남에 따라 모든 행이 메모리에 저장되므로 이 작업이 실패할 수 있습니다.

관련 정보