파일에서 중복 항목을 제거하는 데 사용하고 있습니다 awk
. 문제는 중복 항목이 발견되면 일련의 줄을 제거하고 싶다는 것입니다. 예를 들어 -
<p>
This is duplicate.
</p>
<p>
This is original.
</p>
<p>
This is duplicate.
</p>
나는 그것을 바꾸고 싶다 -
<p>
This is duplicate.
</p>
<p>
This is original.
</p>
행이 반복되면 이전 행과 다음 행을 삭제하십시오. 도움을 주시면 대단히 감사하겠습니다.
현재 사용하고 있습니다 -
awk -i inplace '!seen[$0]++' name_of_file
중복 행을 제거했지만 이전 행과 다음 행을 제거하는 방법을 알 수 없습니다.
답변1
당신이 정말로 원하는 것은 <p>...</p>
개별 행이 아닌 중복된 구분 레코드를 제거하는 것입니다. 게시한 예를 보면 이는 GNU awk입니다(이미 -i inplace)
다중 문자 RS에 사용하고 있음:
$ awk 'BEGIN{RS=ORS="</p>\n"} !seen[$0]++' file
<p>
This is duplicate.
</p>
<p>
This is original.
</p>
이는 레코드에 있는 행 수에 관계없이 작동합니다 <p>...</p>
. 예를 들어 중복 레코드가 여러 행인 경우 다음과 같이 입력합니다.
$ cat file
<p>
This
is
duplicate.
</p>
<p>
This is original.
</p>
<p>
This
is
duplicate.
</p>
이 스크립트는 여전히 중복 항목을 제거합니다.
$ awk 'BEGIN{RS=ORS="</p>\n"} !seen[$0]++' file
<p>
This
is
duplicate.
</p>
<p>
This is original.
</p>
답변2
awk
xml
구문 분석 / 데이터 에 적합한 도구가 아니며 html
입력 형식이 약간 변경되면 실패합니다.
BeautifulSoup
예를 들어 다음과 같은 지정된 파서를 사용하는 것이 좋습니다 python
.
#!/usr/bin/env python3
from bs4 import BeautifulSoup
with open('file.html') as f:
content = f.read()
soup = BeautifulSoup(content, "html.parser")
p_contents=[]
for p in soup.find_all('p'):
p_content = p.get_text().strip()
if p_content in p_contents:
p.extract()
else:
p_contents.append(p_content)
print(soup)
사용 awk
:
awk -v start="<p>" -v end="</p>" '
$0 == start { tag=$0; in_tag=1 }
!in_tag
in_tag && ( $0 != start && $0 != end ) { tag=tag"\n"$0 }
$0 == end { if (!seen[tag]++) { print tag"\n"$0 }; in_tag=0 }
' file.html
답변3
진실은: 나는 당신과 어떻게 할 수 있는지 모르겠습니다 awk
.sed
sed 'N;/\n</{P;D;};G;/\(\n[^<]*\n\).*\1/{N;d;};s/\n\n.*//;s/\n$//;H' file
아이디어는 N;P;D
루프를 사용하여 항상 두 줄을 함께 처리하는 것입니다. 두 번째가 배너가 아닌 경우 예약된 공간에 예약된 라인이 중복되는지 테스트합니다. d
중복된 항목을 제거하고 H
나중에 참조할 수 있도록 새 원본을 기존 공간에 첨부하세요.
-i
파일이 복잡해지지 않도록 먼저 옵션 없이 테스트해 보세요 . 효과가 있고 sed
솔루션이 효과가 있다면 더 자세한 설명을 추가하겠습니다.