たとえば、コンマで区切られた単語を含むプレーンテキストファイルがあります。
word1, word2, word3, word2, word4, word5, word 3, word6, word7, word3
重複を削除して、次のようになりたいです。
word1, word2, word3, word4, word5, word6, word7
何か案は?egrepは私を助けることができると思いますが、正確にどのように使用するかはわかりません。
たとえば、コンマで区切られた単語を含むプレーンテキストファイルがあります。
word1, word2, word3, word2, word4, word5, word 3, word6, word7, word3
重複を削除して、次のようになりたいです。
word1, word2, word3, word4, word5, word6, word7
何か案は?egrepは私を助けることができると思いますが、正確にどのように使用するかはわかりません。
単語が1行に1つあり、ファイルがすでにソートされていると仮定します。
uniq filename
ファイルがソートされていない場合:
sort filename | uniq
それらが1行に1つではなく、1行に1つであってもかまわない場合:
tr -s [:space:] \\n < filename | sort | uniq
ただし、句読点は削除されないので、次のようにします。
tr -s [:space:][:punct:] \\n < filename | sort | uniq
しかし、それはハイフンでつながれた単語からハイフンを削除します。その他のオプションについては「mantr」。
ruby -pi.bak -e '$_.split(",").uniq.join(",")' filename
?
私は2種類の引用が醜いことを認めます。
のおかげで、一意のリストを作成するのは非常に簡単ですがuniq
、ほとんどのUnixコマンドは、コンマ区切りのリストではなく、1行に1つのエントリを使用するため、次のように変換する必要があります。
$ sed 's/, /\n/g' filename | sort | uniq
word1
word2
word3
word4
word5
word6
word7
難しいのは、ターミネータではなく、区切り文字としてコンマを使用して、これを1行にもう一度配置することです。私はこれを行うためにperlワンライナーを使用しましたが、誰かがもっと慣用的なものを持っている場合は、私を編集してください。:)
$ sed 's/, /\n/g' filename | sort | uniq | perl -e '@a = <>; chomp @a; print((join ", ", @a), "\n")'
word1, word2, word3, word4, word5, word6, word7
重複する単語のみを削除して、各行をそのまま残すawkスクリプトを次に示します。
BEGIN {
FS=", "
}
{
for (i=1; i <= NF; i++)
used[$i] = 1
for (x in used)
printf "%s, ",x
printf "\n"
split("", used)
}
今日も同じ問題がありました。238,000語の単語リストですが、そのうち約40,000語が重複しています。私はすでにそれらを個別の行に持っていました
cat filename | tr " " "\n" | sort
重複を削除するために私は単にしました
cat filename | uniq > newfilename .
エラーなしで完全に機能し、ファイルが1.45MBから1.01MBに減少しました
スペースを改行に置き換え、 uniqコマンドを使用して一意の行を見つけてから、改行をスペースに再度置き換えたいと思います。
ファイル全体ではなく、1行で単語を一意にする必要があると思います。この場合、以下のPerlスクリプトでうまくいきます。
while (<DATA>)
{
chomp;
my %seen = ();
my @words = split(m!,\s*!);
@words = grep { $seen{$_} ? 0 : ($seen{$_} = 1) } @words;
print join(", ", @words), "\n";
}
__DATA__
word1, word2, word3, word2, word4, word5, word3, word6, word7, word3
ファイル全体に一意性が必要な場合は、%seen
ハッシュをwhile (){}
ループの外に移動するだけです。
ほぼ同じ問題を解決しようとしているときに、このスレッドに出くわしました。パスワードを含むいくつかのファイルを連結していたので、当然、doubleがたくさんありました。また、多くの非標準文字。並べ替える必要はありませんでしたが、uniqでは必要だったようです。
私は試した:
sort /Users/me/Documents/file.txt | uniq -u
sort: string comparison failed: Illegal byte sequence
sort: Set LC_ALL='C' to work around the problem.
sort: The strings compared were `t\203tonnement' and `t\203tonner'
試した:
sort -u /Users/me/Documents/file.txt >> /Users/me/Documents/file2.txt
sort: string comparison failed: Illegal byte sequence
sort: Set LC_ALL='C' to work around the problem.
sort: The strings compared were `t\203tonnement' and `t\203tonner'.
そして、最初にそれを猫に通してみましたが、それは私たちが適切な入力を得ているかどうかを確認するためです。
cat /Users/me/Documents/file.txt | sort | uniq -u > /Users/me/Documents/file2.txt
sort: string comparison failed: Illegal byte sequence
sort: Set LC_ALL='C' to work around the problem.
sort: The strings compared were `zon\351s' and `zoologie'.
何が起こっているのかわかりません。文字列「t\203tonnement」と「t\203tonner」はファイルに見つかりませんが、「t / 203」と「tonnement」は見つかりますが、別々の隣接していない行にあります。「zon\351s」と同じです。
最終的に私のために働いたのは:
awk '!x[$0]++' /Users/me/Documents/file.txt > /Users/me/Documents/file2.txt
また、大文字と小文字だけが異なる単語も保存されていました。これが私が望んでいたことです。リストを並べ替える必要がなかったので、並べ替えなくても大丈夫でした。
また、単語の数も取得したい場合は-c
、ユーティリティのオプションを忘れないでください。uniq
vim()でファイルを開きvim filename
、一意のフラグ(:sort u
)でsortコマンドを実行します。