Определение общих элементов в нескольких файлах - PullRequest
3 голосов
/ 02 января 2012

У меня есть 8 файлов одного столбца и неодинаковое количество строк в каждом столбце.Мне нужно определить элементы, которые являются общими во всех этих 8 файлах.

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

Любые идеи .....

Заранее спасибо.

Файл 1
Пол
Паван

Файл 2
Раман
Пол
Сладкий
Баруа

Файл 3
Сладкий
Баруа
Пол

Ответсравнение этих трех файлов должно быть Павлом.

Ответы [ 6 ]

7 голосов
/ 02 января 2012

Следующие однострочные должны делать (измените 3 на 8, чтобы соответствовать вашему случаю)

$ sort * | uniq -c | grep 3
      3 Paul

Вероятно, лучше сделать это на python, используя sets ...

4 голосов
/ 02 января 2012
python -c 'import sys;print "".join(sorted(set.intersection(*[set(open(a).readlines()) for a in sys.argv[1:]])))' File1 File2 File3

печатает Paul для ваших файлов File1, File2 и File3.

3 голосов
/ 02 января 2012

Perl

$ perl -lnE '$c{$_}{$ARGV}++ }{ print for grep { keys %{$c{$_}} == 8 } keys %c;' file[1-8]

Должна быть возможность избавиться от жесткого кода 8, а также @{[ glob "@ARGV" ]}, но у меня нет времени проверять это сейчас.

Это решение будет правильно обрабатывать наличие дублирующих строк в файлах.

2 голосов
/ 02 января 2012

Здесь я пытался найти краткий способ убедиться, что каждое совпадение происходит из другого файла.Если в файлах нет дубликатов, это довольно просто в perl:

perl -lnwE '$a{$_}++; END { for (keys %a) { print if $a{$_} == 3 } }' files*

Опция -l автоматически скомпонует ваш ввод (удалит новую строку) и добавит новую строку в печать.Это важно в случае отсутствия eof новых строк.

Опция -n будет читать входные данные из аргументов имени файла (или stdin).

Назначение хэша будет считать дубликаты, а блок ENDраспечатает, какие дубликаты появились 3 раза.Измените 3 на любое количество имеющихся у вас файлов.

Если вам нужна более гибкая версия, вы можете посчитать аргументы в блоке BEGIN.

perl -lnwE 'BEGIN { $n = scalar @ARGV } 
    $a{$_}++; END { for (keys %a) { print if $a{$_} == $n } }' files*
1 голос
/ 02 января 2012

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

ls file{1..3} | 
xargs -n1 sort -u | 
sort | 
uniq -c | 
sed 's/^\s*'"$(ls file{1..3} | wc -l)"'\s*//p;d'
1 голос
/ 02 января 2012
$ awk '++a[$0]==3' file{1..3}.txt
Paul

обновление

$ awk '(FILENAME SEP $0) in b{next}; b[FILENAME,$0]=1 && ++a[$0]==3' file{1..3}.txt
Paul
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...