Покажите местоположения дублирующихся строк через несколько файлов

У меня есть два файла:

#a.txt

11
22
33
44
55
11

И

# b.txt

55 
66 
77 
88 
99 
11

Я делаю эту команду для печати дублирующихся строк через два файла: sort *.txt | uniq -D И это производит:

11
11
11
55
55

Я хотел бы, чтобы это произвело точные местоположения; т.е. для строки 1 от вывода это должно сказать, куда это прибыло из: строка 1, файл a.txt т.е. своего рода различное.

Какие-либо идеи, как я могу сделать это?

1
задан 2 November 2019 в 02:05

2 ответа

TL; DR

можно сделать что-то вроде этого:

file_expr="*.txt"; sort $file_expr | sed 's/^\s*//; s/\s*$//; /^\s*$/d' | uniq -d | while read dup_line; do grep -Hn "^\s*$dup_line\s*$" $file_expr; done| sort -t: -k3 -k1,2 | awk -F: '{ file=$1; line=$2; $1=$2=""; gsub(/(^[ \t]+)|([ \t]+$)/,"",[110]); if (prev != "" && prev != [110]) printf ("\n"); printf ("\033[0;33m%s (line %s)\033[0m: %s\n", file, line, [110]); prev=[110]; }'

Результат:

a.txt (line 3): 11
a.txt (line 8): 11
b.txt (line 8): 11

a.txt (line 7): 55
b.txt (line 3): 55

Изменение содержание переменной file_expr для изменения файлов влияло

<час>

Объяснение

, я использовал эти sed команда к [1 136] обрезка весь запаздывание и продвижение , пробелы и удаляют пустые строки , делание эти uniq -d получает только строки, которые являются ДЕЙСТВИТЕЛЬНО дубликатом...

Затем я цикл по дублирующимся строкам (распечатал один для каждого соответствия), и я grep их в файлы с помощью флагов -n ( строка файла и печати ) и -H ( всегда показывают имя файла ). Выражение ^\s*$dup_line\s*$ в эти grep заставляет его соответствовать целая строка (так, чтобы, например, "стандартное расположение букв на клавиатуре 11 uiop" не соответствовал).

, Как Вы видите, это работает оба использования файл globbing ...

file_expr="*.txt"; sort $file_expr | sed 's/^\s*//; s/\s*$//; /^\s*$/d' | uniq -d | while read dup_line; do grep -Hn "^\s*$dup_line\s*$" $file_expr; done

Результат:

a.txt:3:11  
a.txt:8:11  
b.txt:8:11  
a.txt:7:55  
b.txt:3:55  

... и литеральные имена файлов ..

file_expr="a.txt b.txt"; sort $file_expr | sed 's/^\s*//; s/\s*$//; /^\s*$/d' | uniq -d | while read dup_line; do grep -Hn "^\s*$dup_line\s*$" $file_expr; done

Результат:

a.txt:3:11
a.txt:8:11
b.txt:8:11
a.txt:7:55
b.txt:3:55
<час>

Небольшие Тонкие настройки

я затем играл вокруг немного для создания его визуально больше удобный ... Как это:

file_expr="a.txt b.txt"; sort $file_expr | sed 's/^\s*//; s/\s*$//; /^\s*$/d' | uniq -d | while read dup_line; do grep -Hn "^\s*$dup_line\s*$" $file_expr; done| sort -t: -k3 -k1,2 | awk -F: '{ file=$1; line=$2; $1=$2=""; gsub(/(^[ \t]+)|([ \t]+$)/,"",[116]); if (prev != "" && prev != [116]) printf ("\n"); printf ("\033[0;33m%s (line %s)\033[0m: %s\n", file, line, [116]); prev=[116]; }'

Результат:

a.txt (line 3): 11
a.txt (line 8): 11
b.txt (line 8): 11

a.txt (line 7): 55
b.txt (line 3): 55

В этом последнем представлении все является более "человеческим", и дубликаты группируются сначала результатом и затем файлом (Вы видите, что результаты в [1 116] являются всеми вместе), таким образом, легче понять..

имя файла и строка теперь желтые (\033[0;33m) для различения от текста в фактической строке в случае мультилинии (извините игру слов слова), дубликаты

0
ответ дан 7 December 2019 в 18:18

С тех пор в Вашем примере b.txt файл имеет пробелы в нем, можно использовать awk для захвата символов перед пространством.

Преобразование из моих комментариев выше к ответу здесь. Можно использовать grep -n для показа номера строки и файла, из которого он прибыл. Также добавьте в еще одном uniq команда так, чтобы, когда grep циклы через дубликаты нашли, она не проходила 3 11 и 2 55.

Быстрый пример:

sort *.txt | awk '{print $1}' | uniq -D 
11
11
11
55
55

Путем добавления во втором uniq вывод только:

11
55

Теперь мы можем добавить в grep и while цикл. grep покажет нам, сколько раз каждый появляется и в каком файле они находятся.

sort *.txt | awk '{print $1}' | uniq -D | uniq | while read num; do grep -n $num *.txt; done

Пример:

$ sort *.txt | awk '{print $1}' | uniq -D | uniq | while read num; do grep -n $num *.txt; done
a.txt:2:11
a.txt:7:11
b.txt:7:11
a.txt:6:55
b.txt:2:55 
0
ответ дан 7 December 2019 в 18:18

Другие вопросы по тегам:

Похожие вопросы: