何千ものjsonファイルがあるフォルダがあります。各フォルダの内容は次のとおりです。
file.1424-417982.json
file.1424-417995.json
file.1424-418013.json
file.1424-418015.json
(etc.)
一部のファイルには、フォルダ内の他のファイルと重複する行が含まれています。たとえば、単一行
{"a":"fas8d\U0001f638f8gej3","b":527239835}
で発生する可能性があります
file.1424-417982.json
file.1424-418013.json
または別のファイルにあります。
すべてのファイルを繰り返し、ファイル内のどの行が繰り返されるかを記録し、ファイルからすべての項目を削除する(最初の項目はそのままにする)スクリプトを実行したいと思います。
頑張った
sort -u *.json > newfile
そして、すべてのファイルに一意の行を含む巨大な単一のファイルを作成しましたが、この方法は私には効果がありませんでした。既存のファイル構造を維持したいです。どんなヒントでもありがとう!
答え1
ファイル名にスペースや特殊文字がないと仮定すると、この方法は適切です。最初に処理されるファイルの所望のソート順序を得るために、最初のコマンドを調整する必要があるかもしれない。
#!/bin/bash
temp=$(mktemp)
for file_to_dedupe in $(echo *.json|sort)
do
for file_to_strip in *.json
do
[ "$file_to_dedupe" == "$file_to_strip" ] && continue
grep -w -Ff ${file_to_dedupe} -v ${file_to_strip} > ${temp}
mv ${temp} ${file_to_strip}
done
done
説明する
temp=$(mktemp)
使用するtmpファイルを作成します。for file_to_dedupe in $(echo *.json|sort)
重複したファイルを削除するには、ファイルの繰り返しを開始してください。for file_to_strip in *.json
重複を削除するには、ファイルを繰り返し起動します。[ "$file_to_dedupe" == "$file_to_strip" ] && continue
現在のファイルをスキップします。grep -w -Ff ${file_to_dedupe} -v ${file_to_strip} > ${temp}
正確なトリックを排除するために各行をパターンとして使用file_to_dedupe
mv ${temp} ${file_to_strip}
新しいファイルを所定の位置に配置します。
答え2
perl -i.bak -ne 'print $_ unless $a{$_}++ ' *.json
削除します(files.bak
有効な場合)。