Сравнение строк (структурированный текст) в ударе

Я должен сравнить два файла (new.txt и old.txt) со следующей структурой:

 ,,,,, 
  1. The common lines must be skipped.
  2. Similar line from new.txt and old.txt should be grouped. I suppose that line from old.txt is similar to line from new.txt if Field1, Field2, Field3, Field4 are the same.
  3. Other unique lines should be printed below grouped by file name

, Таким образом, задача конца состоит в том, чтобы сделать визуальное сравнение легче.

Added part: Example.

$ cat old.txt 
 one,two,three,four,five,six
 un,deux,trois,quatre,cinq,six
 eins, zwei, drei, vier, fünf, sechs
$ cat new.txt 
 one,two,three,four,FIVE,SIX
 un,deux,trois,quatre,cinq,six
 en,två,tre,fyra,fem,sex

$cat comparison_result:
# lines are grouped. So it it easy to find the difference without scrolling.
old.txt> one,two,three,four,five,six
new.txt> one,two,three,four,FIVE,SIX
# end of task 2. There are no more simillar lines.
#
#start task 3.
#Printing all the rest unique lines of old.txt 
echo "the rest unique line in old.txt"
eins, zwei, drei, vier, fünf, sechs
.... 
#Printing all the rest unique lines of new.txt
echo "the rest unique line in new.txt"
en,två,tre,fyra,fem,sex

Это может быть шагом 1: пропускать общие линии.

 # This is only in old.txt
 comm -2 -3 <(sort old.txt) <(sort new.txt) > uniq_old

 # This is only in new.txt
 comm -1 -3 <(sort old.txt) <(sort new.txt) > uniq_new

Я написал шаг 1 и эту сортированную разность как временное решение:

 # additional sort improves a bit diffs results.
 diff <(sort uniq_old) <(sort uniq_new)

Это работает, но не идеальное. Я отказался использовать разность, потому что она начинает сравнивать блоки, пропуская общие линии.

Есть ли лучший способ удовлетворить 3 требования, написанные выше?

Я думаю, что это может быть сделано

  1. некоторые улучшения этого вида, разности и команд коммуникации (добавляющий sed/tr временному служащему "скрывают" последние поданные два и сравнивают остальных).
  2. awk

Я предполагаю, что awk может сделать это лучше?

1
Что, если линия в new.txt идентична одной линии в old.txt , но подобна различной линии? Линия пропускается или группируется?
добавлено автор ghoti, источник
Кроме того, какого черта вы делаете? Это кажется, что могло бы очень хорошо быть Проблема XY.
добавлено автор ghoti, источник
Файлы сортированы каким-либо конкретным способом? Я думаю, что 1) <закодировал> бы коммуникацию-3 , чтобы устранить все линии, которые происходят в обоих файлах, 2) вид остаток (чтобы получить вашу группу № 2 друг рядом с другом), 3) используют awk , чтобы дифференцироваться между строками № 2 и линиями № 3 (сравнивая области 1-4 на каждой линии с ценностями от предыдущей линии и делая что-то другое на основе того сравнения - ваш выше коммуникация , команды достаточны для линий № 3).
добавлено автор twalberg, источник
Спасибо за совет!
добавлено автор idobr, источник
@ghoti, Что, если линия в new.txt идентична одной линии в old.txt, но подобна различной линии? Это пропускается.
добавлено автор idobr, источник
Так, вероятно, лучше сравнить uniq_old и uniq_new.
добавлено автор idobr, источник

1 ответы

Что относительно этого?

awk -F, 'NR==FNR{old[$0];next} $0 in old{delete old[$0];next} 1 END{for(line in old) print line}' old.txt <(sort -u new.txt) | sort

Давайте разломаем его на части.

  • -F, tells awk to use a , as a field separator.
  • NR==FNR{old[$0];next} - In cases where NR (record/line number) matches the line number in the current file (that is, while we're reading the first input file), stores the whole line as the index of an associative array, then jumps to the next record.
  • $0 in old{delete old[$0];next} - Now we're reading the second file. If the current line is in the array, delete if from the array and move on. This address condition #1 in your question.
  • 1 - short hand in awk for "print the line". This addresses part of condition #3 in your question by printing unique lines from the second file.
  • END{...} - this loop prints everything that wasn't deleted from the array. This addresses the other part of condition #3 by printing unique lines from the first file.
  • <(sort -u new.txt) - uniques the input of new.txt. If you know that new.txt is unique already, you can remove this bash dependency.
  • | sort sorts the output, "grouping" things per condition #2 in your question.

Типовая продукция:

 $ cat old.txt 
 one,two,three,four,five,six
 un,deux,trois,quatre,cinq,six
 $ cat new.txt 
 one,two,three,four,FIVE,SIX
 un,deux,trois,quatre,cinq,six
 en,två,tre,fyra,fem,sex
 $ awk -F, 'NR==FNR{old[$0];next} $0 in old{delete old[$0];next} 1 END{for(line in old) print line}' old.txt new.txt | sort
 en,två,tre,fyra,fem,sex
 one,two,three,four,FIVE,SIX
 one,two,three,four,five,six
 $ 

Обратите внимание, что линия на французском языке была дублирована, таким образом пропущена. Все остальное было напечатано с двумя английскими линиями, "сгруппированными", сортировав.

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

 $ sort old.txt new.txt | awk '$0==last{last="";next} last{print last} {last=$0} END{print last}' | sort
 en,tva,tre,fyra,fem,sex
 one,two,three,four,FIVE,SIX
 one,two,three,four,five,six
 $ 

Идея здесь состоит в том, что вы просто берете ВСЕ входные данные из своих файлов, сортируете их, затем используйте awk сценарий, чтобы пропустить повторенные линии и напечатать все остальное. Тогда сортируйте продукцию. Это работает над потоком, насколько awk затронут, но быть предупрежденным, что для очень большого входа, ваш вид команда все еще должна загрузить данные в файлы временного секретаря и/или память.

Кроме того, как есть это второе решение терпит неудачу, если конкретная линия повторяется несколько раз. Таким образом, если это существует однажды в old.txt и дважды в new.txt. Вы нуждаетесь к уникальному в своих входных файлах или приспосабливаете сценарий к той ситуации.

1
добавлено
Прекрасные взгляды! Спасибо за такой подробный ответ. I' m собирающийся проверять это прямо сейчас.
добавлено автор idobr, источник
Ваши awk хорошие работы выражения! (Я добавил новую строку перед КОНЦОМ, чтобы избежать ошибочной тревоги), В настоящее время это doesn' t делают точно, в чем я нуждаюсь. Я должен отредактировать вопрос быть более точным. Задача конца состояла в том, чтобы сделать визуальное сравнение файлов легче. I' ll пытаются зафиксировать его самостоятельно.
добавлено автор idobr, источник
pro.bash
pro.bash
123 участник(ов)

All about Nix shells, signals, processes and development in general.