2013-06-28 6 views
2

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

Первый (file1), как так: (всегда есть headerline перед «text'line)

>random header name1 
wonderfulstringwhatsoevergoeson 
>random header 2 
someotherline 
... 

Другой файл (file2) является доработанный файл file1 как: (заголовок, были удалены, и линии перемешиваются, новый заголовок был добавлен)

>name 
someotherline 
wonderfulstringwhatsoevergoeson 

Каждая строка (без заголовка) из file1 происходит в file2. Порядок строк в file2 отличается от file1. Оба файла должны оставаться в том порядке, в котором они есть.

Каждая строка в file2

выход должен быть чем-то похожи: (заголовок file2 можно пренебречь)

>random header 2 
>random header name1 

Кто-подсказкой, как это сделать?

С наилучшими пожеланиями

+2

Уверяю вас, они могут быть отсортированы. – ctn

+0

Что это значит: их нельзя сортировать? Они слишком большие? Или это поток, а не сам файл? Это важно, потому что причина не сортировки может ограничить ваши варианты. В общем, как я понимаю, вы хотите найти строки, которые являются уникальными в обоих файлах. Обычно это делается с помощью: 'cat files * | сортировать | uniq -u' –

+0

@depesz: Чтобы избежать бесполезных змеев, используйте 'sort files * | uniq -u'. – TrueY

ответ

2

Код для GNU :

 
$sed '/^[>]/N;s#\(.*\)\n\(.*\)#/\2/s/.*/\1/p#' file1|sed -nf - file2 
>random header 2 
>random header name1 
+0

Спасибо вам большое! Вы решили мою проблему :) – user2525078

3

Учитывая разъяснения, что файлы должны оставаться такой же, просто используйте:

sort file1 file2 file2 | uniq -u 

и вы сделали.

В качестве альтернативы, если файлы большие, так что сортировка (file1 + file2 + file2) слишком много нагрузки, вы можете использовать это:

comm -23 <(sort file1) <(sort file2) 

который будет только сортировать каждый файл (файл на диске будет сохранен так, как он есть, он не будет изменен), а затем распечатать строки, которые существуют в файле1, но не в файле2.

Пример:

=$ cat file1 
some header 
abc 
cdf 
efg 
other header 

=$ cat file2 
file2 header 
cdf 
file2 header part2 
efg 
abc 

=$ comm -23 <(sort file1) <(sort file2) 
other header 
some header 
2

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

#!/bin/bash 

cat file2 | 
while read line; do 
    grep -B 1 "$line" file1 | head -n1 
done 

grep -B 1 напечатает одну строку перед матчем. Мы можем отрезать первую строчку головой.
Это можно назвать хаком. (Но я все еще новичок).

файл1:

> случайным образом заголовка имя1
wonderfulstringwhatsoevergoeson
> случайным образом заголовка 2
someotherline

файл2:

someotherline
wonderfulstringwhatsoevergoeson

Выход:

> случайный заголовок 2
> случайный заголовок name1

также понять это решение, как указывал depesz медленно.

+0

Этот подход будет довольно медленным, так как он должен будет grep file2 N раз, где N - количество строк в файле2. Кроме того, я не уверен, что это то, чего хотел ОП, но я оставляю это для него, чтобы судить, так как я не уверен, что понимаю его описание. –

+0

@mohit Большое вам спасибо! Это довольно близко к тому, что я искал! Что мне делать, если заголовок - это линия впереди, а не в той же строке? – user2525078

+0

@ user2525078 Исправлено. – mohit