2012-02-21 6 views
119

Я хочу удалить дубликаты записей из текстового файла, например:Удаление повторяющихся записей с помощью Bash скрипт

kavitha= Tue Feb 20 14:00 19 IST 2012 (duplicate entry) 
sree=Tue Jan 20 14:05 19 IST 2012 
divya = Tue Jan 20 14:20 19 IST 2012 
anusha=Tue Jan 20 14:45 19 IST 2012 
kavitha= Tue Feb 20 14:00 19 IST 2012 (duplicate entry) 

Есть ли возможный способ для удаления повторяющихся записей с помощью Bash сценарий?

Желаемая выход

kavitha= Tue Feb 20 14:00 19 IST 2012 
sree=Tue Jan 20 14:05 19 IST 2012 
divya = Tue Jan 20 14:20 19 IST 2012 
anusha=Tue Jan 20 14:45 19 IST 2012 
+17

* Запрашиваемая, как удалить дубликаты. Вопрос становится помеченным как дубликат. * – sysfiend

+0

* Это вопрос об удалении дубликатов. Он был отмечен как дубликат. * –

ответ

264

Вы можете sort затем uniq:

$ sort -u input.txt 

Или используйте awk:

$ awk '!a[$0]++' input.txt 
+38

Тестирование с текстовым файлом в 18 500 строк: 'sort ...' занимает около 0,57, тогда как' awk ... 'занимает около 0,08, потому что' awk ... 'просто удаляет дубликаты без сортировка. – Hugo

+2

@ Хьюго, я могу это повторить. Тестирование против 2,626,198 строк 'awk' бьет' sort'. Результаты показывают, что 'awk' занимает 5.675s и' sort' занимает 5.675s. Интересно, что один и тот же набор записей занял 15,1 секунды для выполнения запроса MySQL DISTINCT. –

+0

@TeganSnyder Вы написали, что обе команды заняли ровно одно и то же время для выполнения. Разве 'awk' не занимал меньше времени? – jarno

7

Он удаляет дубликаты, последовательные строки из F ile (эмулирует «uniq»).
Сохраняется первая строка в наборе повторяющихся строк, остальные удаляются.

sed '$!N; /^\(.*\)\n\1$/!P; D' 
+0

, работал для меня, Еще одно дополнение для другого использования, Если вы хотите изменить файл сама здесь - команда 'sed -i '$! N; /^\(.*\)\n\1$/!P; D ' ' –

0

Это может работать для вас:

cat -n file.txt | 
sort -u -k2,7 | 
sort -n | 
sed 's/.*\t/ /;s/\([0-9]\{4\}\).*/\1/' 

или это:

awk '{line=substr($0,1,match($0,/[0-9][0-9][0-9][0-9]/)+3);sub(/^/," ",line);if(!dup[line]++)print line}' file.txt 
2

Perl один лайнер аналогично решению AWK @ Кева:

perl -ne 'print if ! $a{$_}++' input 

Это изменение удаляет конечные пробелы перед сравнением:

perl -lne 's/\s*$//; print if ! $a{$_}++' input 

Это изменение редактирует файл на месте:

perl -i -ne 'print if ! $a{$_}++' input 

Это изменение редактирует файл на месте, и делает резервную копию input.bak

perl -i.bak -ne 'print if ! $a{$_}++' input 
Смежные вопросы