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

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

나는 일부 줄이 반복되는 ~ 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시간이 지남에 따라 모든 줄이 메모리에 저장되므로 이 작업이 실패할 수 있습니다.

관련 정보