2016-01-30 1 views
-1

Пусть мы имеем ~/file1:Слияние двух, почти Подобный Text Files

line1 
line2 
line3 

... и ~/file2:

line1 
lineNEW 
line3 

Обратите внимание, что Thes два файла почти идентичны, за исключением line2 отличается от lineNEW.

Вопрос: Как я могу объединить эти два файла, чтобы произвести один, который гласит:

line1 
line2 
lineNEW 
line3 

То есть, как я могу объединить два файла так, чтобы все уникальные линии фиксируются (без перекрытия) в третий файл? Обратите внимание, что порядок строк не имеет значения (пока все уникальные строки захватываются).

+0

Может вы не создаете файл патча на основе 'diff', а затем просто удаляете строки удаления из него перед его применением? – arkascha

+0

Если вы на самом деле используете bash или другую оболочку, которая поддерживает чтение из дескрипторов файлов, вы можете перенаправить второй файл в отдельный дескриптор, а затем просто сравнить содержимое по строкам. например 'while read -r linea; прочитайте -r -u 3 lineb; ["$ a" = "$ b"] ...; done <файл1 3 <файл2'. –

+0

Джордж, в то время как вы проделали отличную работу по разъяснению своей цели, включая выборочные данные и ожидаемый результат, другим важным компонентом вопроса StackOverflow является попытка, которую * вы * решили решить самостоятельно. Эксперты рады помочь вам улучшить вашу работу, но мы не программисты с коротким порядком. Пожалуйста, отредактируйте свой вопрос и покажите свою попытку, чтобы мы могли помочь вам улучшить его. – ghoti

ответ

1
awk '{ 
    print 
    getline line < second 
    if ($0 != line) print line 
}' second=file2 file1 

сделает это

+1

можно играть в гольф до 'awk '1; {getline L

+1

или 'paste file1 file2 | awk -F '\ t' '{print $ 1; if ($ 1! = $ 2) print $ 2} '' –

+0

Гленн, это улучшение ∞% по сравнению с кодом в вопросе. Общепринято ли поощрять плохие вопросы, предоставляя им ответы вместо того, чтобы сбрасывать или закрывать их? – ghoti

1

Рассмотренный ниже команду. Он более надежный, так как он также работает с файлами, в которые добавлена ​​новая строка вместо замены (см. Ниже f1 и f2).

Во-первых, я выполнил его, используя ваши файлы. Я разделил команду (ы) в две строки, так что он прекрасно вписывается в «блоке кода»:

$ (awk '{ print NR, $0 }' file1; awk '{ print NR, $0 }' file2) |\ 
sort -k 2 | uniq -f 1 | sort | cut -d " " -f 2- 

Он производит ваш ожидаемый результат:

line1 
line2 
lineNEW 
line3 

Я также использовала эти два дополнительных файлов проверить:

f1:

f2:

line1 stuff after a tab 
lineNEW 
line2 line2 
line3 
line4 
line5 
line6 

Вот команда:

$ (awk '{ print NR, $0 }' f1; awk '{ print NR, $0 }' f2) |\ 
sort -k 2 | uniq -f 1 | sort | cut -d " " -f 2- 

Он производит этот выход:

line1 stuff after a tab 
line2 line2 
lineNEW 
line3 
line4 
line5 
line6 
+0

Это решение выходит из строя, если строка 2 второго файла совпадает с строкой 3 первого файла. По этому вопросу кажется, что только идентичные строки * в одном и том же положении * должны быть «uniq» ed. – ghoti

+0

@ghoti, если только одинаковые строки в одном и том же положении должны быть «uniq» ed, вы правы; это решение не будет работать. Однако я не совсем уверен, что это то, что задают. Последнее утверждение в вопросе - вот что заставляет меня сомневаться: «Обратите внимание, что порядок строк не имеет значения (пока все уникальные строки захватываются)». Может быть, он просто означает порядок двух разных линий в одном и том же положении, но я не был уверен. Использование слова «merge» заставляет меня хотеть согласиться с вами. –

+0

Еще одна вещь, которая заставляла меня сомневаться, состоит в том, что если только строки в одной и той же позиции должны быть «uniq» ed, добавление строки прерывает слияние оттуда. –

1

Если вы не заботитесь о порядке, просто отсортировать их:

cat ~/file1 ~/file2 | sort -u > ~/file3 
Смежные вопросы