LinuxForum.Fans
Тема

Определить повторяющиеся строки

Автор: natalia_nikiforowa 9 сообщений 5094 просмотров
#356191

В заданном файле:
а) определить повторяющиеся строки, вывести их номера
б)оставить в файле только одну из повторяющихся строк

Помогите, пожалуйста, разобраться.

вот что получается :

text
cat -n file.txt | sort | uniq -f 2 -d

Объясните как нужно, пожалуйста.

#356245

Насколько я помню, для uniq надо, чтобы повторяющмеся строки шли подряд,
т.е. файл должен быть отсортированным, так что нужен отдельный скрипт
и grep с опцией "-n" - выводить номера строк. Но сам я этого не делал.
Ещё есть comm для сравнения отсортированных файлов.

Пётр.

#356271
text
$ cat -n file
     1  aaa
     2  bbb
     3  ccc
     4  ddd
     5  qqq
     6  aaa
     7  fff
     8  bbb
     9  sss
    10  ddd
    11  lll
    12  111
    13  rrr
    14  666
    15  ddd
    16  333
    17  ccc
    18  111
    19  ddd

echo "Номера повторяющихся строк"; sort file | uniq -d | while read line; do cat -n file | grep $line; done | sort -n | awk '{print $1}'; echo -e "\nОтсортированный файл с удаленными повторами строк"; sort -u file Номера повторяющихся строк 1 2 3 4 6 8 10 12 15 17 18 19

Отсортированный файл с удаленными повторами строк 111 333 666 aaa bbb ccc ddd fff lll qqq rrr sss

Тот же самый однострочник, но в более удобочитаемом виде:

text

echo "Номера повторяющихся строк"
sort file \
| uniq -d \
| while read line; 
do 
  cat -n file | grep $line
done | sort -n | awk '{print $1}'
echo -e "\nОтсортированный файл с удаленными повторами строк"
sort -u file
#356277
"allez" написал:
echo "Номера повторяющихся строк"; sort file | uniq -d | while read line; do cat -n file | grep $line; done | sort -n | awk '{print $1}';

Не знаток баша, но так проще, кажись) :

text

$ for i in $(sort file.txt | uniq -d); do grep -n $i file.txt | cut -f1 -d:; done
#356288

прошу прощения, с похмела то тяжко и работа отвлекает

text
gu@moshell:~$ cat string
#!/usr/bin/perl -w

use strict;

my %number; my $number_string; my @list; my %repeat; my @uniq; my %seen; while (<>) { $number_string++; chomp; $number{$_}++; push (@list, $_); $repeat{$_} .= " $number_string" }

foreach my $item ( @list ) { push( @uniq, $item) unless $seen{$item}++; }

for ( @uniq ) { print "The string : \"", $_, "\" found ", $number{$_}, " time(s) at line ", $repeat{$_}, "\n"; }

text
gu@moshell:~$ cat file
aaa
bbb
ccc
aaa
bbb
aaa
aaa
text
gu@moshell:~$ ./string file
The string : "aaa" found 4 time(s) at line   1  4  6  7
The string : "bbb" found 2 time(s) at line   2  5
The string : "ccc" found 1 time(s) at line   3
gu@moshell:~$
#356295

весь ваш uniq и sort лесом идут, если нельзя менять порядок

#356296
"-=Serj=-" написал:
Не знаток баша, но так проще, кажись) :
"moshell" написал:
весь ваш uniq и sort лесом идут, если нельзя менять порядок

Может, и проще, может, и идут... Но, во-первых, вопрошающая в условиях задачи ничего не оговаривала насчет сохранения порядка, а во-вторых, я не собирался и не собираюсь делать за студиозусов их задания целиком и полностью, да еще просто и красиво. :) Я, как правило, в таких случаях выдаю "быстрый и грязный", но работающий код, "вылизывать" который предоставляю самим студентам, чтобы они совсем уж не расслаблялись. :)

#356299
allez написал:
да еще просто и красиво

ок. в данном случае

text
gu@moshell:~$ ./string file

выглядит еще компактнее.

вы же не собираетесь тут выкладывать код для утилит? :)

allez написал:
вопрошающая в условиях задачи ничего не оговаривала насчет сохранения порядка

вот такое суждение влечет к плохому сопровождению кода

allez написал:
я не собирался и не собираюсь делать за студиозусов их задания целиком и полностью

а мне нравится задачки решать. и людям помощь, и сам чего то новое находишь

allez написал:
в таких случаях выдаю "быстрый и грязный", но работающий код, "вылизывать" который предоставляю самим студентам, чтобы они совсем уж не расслаблялись. :)

тут согласен.

#356676
text
echo -e '111 xxx\n222 yyy\n111 yyy\n333 zzz\n222 yyy' | cat -n | sort -k2 | { z='';x=0; while read a b; do [ "${b}" != "${z}" ] && echo -n -e "\n${b}"; echo -n ":${a}" ; z="${b}"; done; }; echo
Войдите или зарегистрируйтесь, чтобы ответить.