Как удалить дубликаты слов из текстового файла с помощью команды linux
у меня есть простой текстовый файл со словами, которые разделены запятой, например:
word1, word2, word3, word2, word4, word5, word 3, word6, word7, word3
Я хочу удалить дубликаты и стать:
word1, word2, word3, word4, word5, word6, word7
Какие Идеи? Я думаю, для egrep может помочь мне, но я не уверен, как использовать это точно....
10 ответов
предполагая, что слова по одному на строку, и файл уже отсортирован:
uniq filename
если файл не отсортирован:
sort filename | uniq
если они не по одному на строку, и вы не возражаете, что они по одному на строку:
tr -s [:space:] \n < filename | sort | uniq
это не удаляет пунктуацию, хотя, возможно, вы хотите:
tr -s [:space:][:punct:] \n < filename | sort | uniq
но это удаляет дефис из дефисных слов. "man tr" для большего количества вариантов.
создание уникального списка довольно легко благодаря uniq, хотя большинство команд Unix любят одну запись на строку вместо списка, разделенного запятыми, поэтому мы должны начать с преобразования его в это:
$ sed 's/, /\n/g' filename | sort | uniq
word1
word2
word3
word4
word5
word6
word7
сложнее всего поставить это на одну строку снова с запятыми в качестве разделителей, а не Терминаторов. Я использовал Perl one-liner для этого, но если у кого-то есть что-то более идиоматичное, отредактируйте меня. :)
$ 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.45 MB до 1.01 MB
Я думаю, вы захотите заменить пробелы новыми строками, используйте uniq команда для поиска уникальных строк, затем снова замените новые строки пробелами.
я предположил, что вы хотите, чтобы слова были уникальными в одной строке, а не по всему файлу. Если это так, то 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 (){} петли.
наткнулся на эту тему, пытаясь решить ту же проблему. Я объединил несколько файлов, содержащих пароли, поэтому, естественно, было много двойников. Также много нестандартных персонажей. Я не очень нуждался в их сортировке, но, похоже, это было необходимо для 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 `t3tonnement' and `t3tonner'
пробовал:
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 `t3tonnement' and `t3tonner'.
и даже попытался сначала передать его через cat, просто чтобы я мог видеть, получаем ли мы правильное вход.
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 `zon1s' and `zoologie'.
Я не уверен, что происходит. Строки "t\203tonnement" и "t\203tonner" не найдены в файле, хотя "t/203" и "tonnement" найдены, но на отдельных, не смежных строках. То же самое с "zon\351s".
что, наконец, сработало для меня:
awk '!x[]++' /Users/me/Documents/file.txt > /Users/me/Documents/file2.txt
Он также сохранил слова, единственным отличием которых был случай, чего я и хотел. Мне не нужно было сортировать список, так что все было в порядке.--5-->
открыть файл с помощью vim (vim filename) и запустить команду сортировки с уникальным флагом (:sort u).