Как удалить дубликаты слов из текстового файла с помощью команды 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
).