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