2013-10-06 3 views
10

Итак, позвольте мне объяснить это немного больше:Bash. Получить пересечение из нескольких файлов

У меня есть каталог с именем метки, которые имеют файл для каждого тега, что-то вроде:

tags/ 
    t1 
    t2 
    t3 

В каждом из файлов теги это структура, как:

<inode> <filename> <filepath> 

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

То, что я хочу быть в состоянии сделать, это вызвать команду как

tags <t1> <t2> 

и это список файлов, которые имеют ОБА метки t1 и t2 в хорошем способе.

Мой план прямо сейчас должен был создать временный файл. В основном выведите весь файл t1 в него. Затем пропустите каждую строку в t2 и выполните awk в файле. И продолжайте делать это.

Но мне интересно, есть ли у кого-нибудь другие способы. Я не слишком знаком с AWK, Grep и т.д.

+0

Может ли одна и та же строка появляться несколько раз в одном файле? –

+0

Нет. У меня есть это прямо сейчас, так как файл будет только в файле тегов один раз. – Jonovono

+0

BashFAQ # 36 находится по адресу: http://mywiki.wooledge.org/BashFAQ/036 –

ответ

13

Вы можете использовать

sort t1 t2 | uniq -d 

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

Это предполагает, что каждый файл не содержит дубликатов внутри него и что inodes одинаковы во всех структурах для определенного файла.

+0

Это потрясающе. Намного проще, спасибо!Однако это не удается, если вы пытаетесь просто перечислить из одного файла тега: sort t1 | uniq -d. (любое решение для этого?) – Jonovono

+1

Um ... 'cat t1'? :-) –

+1

hah. Я, собирался отредактировать это, так как сразу после того, как я спросил, что я похож на духхх. Большое спасибо :) – Jonovono

15

Вы можете попробовать с comm утилитой

comm -12 <t1> <t2> 

comm с соответствующей комбинацией followinng optionns может быть полезным для различных операций набора на содержимое файла.

-1  suppress column 1 (lines unique to FILE1) 

    -2  suppress column 2 (lines unique to FILE2) 

    -3  suppress column 3 (lines that appear in both files) 

Это предполагает <t1> и <t2> сортируются. Если нет, то они должны быть сначала сортируется с sort

+1

TIL 'comm' после использования linux более десятилетия. Спасибо! –

+2

@AdamLiss Добро пожаловать. Я изучил опцию '-d'' uniq' из вашего решения. Спасибо в ответ. Примите участие в обмене знаниями. ура! – jkshah

+1

Гораздо эффективнее принятого ответа. –

0

Версия для нескольких файлов:

eval `perl -le 'print "cat ",join(" | grep -xF -f- ", @ARGV)' t*` 

Раскрывается в:

cat t1 | grep -xF -f- t2 | grep -xF -f- t3 

Тестовые файлы:

seq 0 20 | tee t1; seq 0 2 20 | tee t2; seq 0 3 20 | tee t3 

Выход:

0 
6 
12 
18 
+0

Это опасно - что, если у вас есть файл с именем 't $ (rm -rf.)'? –

Смежные вопросы