ファイルから重複した項目を削除するために使用しています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
ループを使用して常に2行を一緒に処理することです。 2番目がバナーでない場合は、予約済みスペースに予約済み行が重複しているかどうかをテストします。d
重複したアイテムを削除してH
後で参照できるように、新しいソースを既存のスペースに添付します。
-i
ファイルが複雑にならないように、まずオプションなしでテストしてみてください。効果があり、sed
ソリューションが効果がある場合は、より詳細な説明を追加します。