как использовать патч и разность, чтобы объединить два файла и автоматически разрешить конфликты

Кажется, что у Вас есть намного больше файлов, чем нормальное ожидание.

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

Для создания новой файловой системы с такой огромной inode таблицей необходимо использовать '-N' опция mke2fs (8).

Я рекомендовал бы использовать '-n' опция сначала (который не создает фс, но отображает полезную информацию) так, чтобы Вы могли получить предполагаемое количество inodes. Затем, если Вы должны, используйте '-N' для создания файловой системы с определенные inode числа.

19
20.09.2019, 11:57
8 ответов

Вам не нужно patch для этого; это для извлечения изменений и пересылки их без неизменной части файла.

Инструмент для слияния двух версий файла merge, но как @vonbrand записал, Вам нужен "основной" файл от который Ваши две отличенные версии. Чтобы сделать слияние без него, использовать diff как это:

diff -DVERSION1 file1.xml file2.xml > merged.xml

Это включит каждый набор изменений в C-стиле #ifdef/#ifndef команды "препроцессора", как это:

#ifdef VERSION1
<stuff added to file1.xml>
#endif
...
#ifndef VERSION1
<stuff added to file2.xml>
#endif

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

#ifndef VERSION1
<version 1>
#else /* VERSION1 */
<version 2>
#endif /* VERSION1 */

Поэтому сохраните вывод в файле и откройте его в редакторе. Поиск любых мест, где #else подходит, и разрешите их вручную. Затем сохраните файл и прокрутите его grep -v избавиться от остающегося #if(n)def и #endif строки:

grep -v '^#if' merged.xml | grep -v '^#endif' > clean.xml

В будущем сохраните исходную версию файла. merge может дать Вам намного лучшие результаты с помощью дополнительной информации. (Но быть осторожным: merge редактирования один из оперативных файлов, если Вы не используете -p. Прочитайте руководство).

24
27.01.2020, 19:45
  • 1
    я добавил что-то для того, если у меня был конфликт sed -e "s/^#else.*$/\/\/ conflict/g" –  lockwobr 05.08.2016, 07:31
  • 2
    я не думаю, что это - хорошая идея. Как я записал в своем ответе, необходимо удалять #else строки вручную, в редакторе во время разрешения конфликтов. –  alexis 19.05.2017, 17:53

merge(1) вероятно, ближе к тому, что Вы хотите, но это требует общего предка в Ваши два файла.

(Грязный!) способ сделать его:

  1. Избавьтесь от первых и последних строк, используйте grep(1) исключить их
  2. Разбейте результаты вместе
  3. sort -u оставляет отсортированный список, устраняет дубликаты
  4. Замените первую/последнюю строку

Humm... что-то вдоль строк:

echo '<resources>'; grep -v resources file1 file2 | sort -u; echo '</resources>'

мог бы сделать.

6
27.01.2020, 19:45
  • 1
    действительно работает в этом конкретном примере, но НЕ в целом: Если name in_b_but_different_val имеет значение #00AABB вид поместит это на вершину и стирает второе значение вместо первого –  Rafael T 02.02.2013, 04:16
  • 2
    для оптимального решения в этом случае, необходимо было бы проанализировать XML, с реальным синтаксическим анализатором XML не взломы выше, и произвести новый объединенный вывод XML из этого. разность / патч / вид и т.д. является просто всеми взломами, адаптированными в соответствии с "конкретными примерами" для общего решения, они - просто неправильные инструменты –  frostschutz 02.02.2013, 14:06
  • 3
    @alzheimer, сделали на скорую руку что-то простое, чтобы показать нам... –  vonbrand 02.02.2013, 14:22

Здесь простое решение, которое работает, объединяя до 10 файлов:

#!/bin/bash

strip(){
    i=0
    for f; do
        sed -r '
            /<\/?resources>/ d
            s/>/>'$((i++))'/
        ' "$f"
    done
}

strip "$@" | sort -u -k1,1 -t'>' | sed '
    1 s|^|<resources>\n|
    s/>[0-9]/>/
    $ a </resources>
'

отметьте аргумент, который на первом месте, имеет приоритет, таким образом, необходимо звонить:

script b.xml a.xml

удержаться от общих ценностей b.xml вместо a.xml.

script b.xml a.xml outs:

<resources>
   <color name="in_b_but_different_val">#BBBBBB</color>
   <color name="not_in_a">#AAAAAA</color>
   <color name="not_in_b">#AAAAAA</color>
   <color name="not_in_b_too">#AAAAAA</color>
   <color name="same_in_b">#AAABBB</color>
</resources>
1
27.01.2020, 19:45

Другой ужасный взлом - мог быть упрощен, но :P

#!/bin/bash

i=0

while read line
do
    if [ "${line:0:13}" == '<color name="' ]
    then
        a_keys[$i]="${line:13}"
        a_keys[$i]="${a_keys[$i]%%\"*}"
        a_values[$i]="$line"
        i=$((i+1))
    fi
done < a.xml

i=0

while read line
do
    if [ "${line:0:13}" == '<color name="' ]
    then
        b_keys[$i]="${line:13}"
        b_keys[$i]="${b_keys[$i]%%\"*}"
        b_values[$i]="$line"
        i=$((i+1))
    fi
done < b.xml

echo "<resources>"

i=0

for akey in "${a_keys[@]}"
do
    print=1

    for bkey in "${b_keys[@]}"
    do
        if [ "$akey" == "$bkey" ]
        then
            print=0
            break
        fi
    done

    if [ $print == 1 ]
    then
        echo "  ${a_values[$i]}"
    fi

    i=$(($i+1))
done

for value in "${b_values[@]}"
do
    echo "  $value"
done

echo "</resources>"
1
27.01.2020, 19:45

Хорошо, вторая попытка, теперь в Perl (не производственное качество, никакая проверка!):

#!/usr/bin/perl

open(A, "a.xml");

while(<A>) {
  next if(m;^\<resource\>$;);
  next if(m;^\<\/resource\>$;);
  ($name, $value) = m;^\s*\<color\s+name\s*\=\s*\"([^"]+)\"\>([^<]+)\<\/color\>$;;
  $nv{$name} = $value if $name;
}

close(A);

open(B, "b.xml");

while(<B>) {
  next if(m;^\<resource\>$;);
  next if(m;^\<\/resource\>$;);
  ($name, $value) = m;^\s*\<color\s+name\s*\=\*\"([^"]+)\"\>([^<]+)\<\/color\>$;;
  $nv{$name} = $value if $name;
}

close(B);

print "<resource>\n";
foreach (keys(%nv)) {
    print "   <color name=\"$_\">$nv{$_}</color>\n";
}
print "</resource>\n";
0
27.01.2020, 19:45

Другой, с помощью сокращения и grep... (берет a.xml b.xml в качестве аргументов),

#!/bin/bash

zap='"('"`grep '<color' "$2" | cut -d '"' -f 2 | tr '\n' '|'`"'")'
echo "<resources>"
grep '<color' "$1" | grep -E -v "$zap"
grep '<color' "$2"
echo "</resources>"
0
27.01.2020, 19:45
  • 1
    echo действие по умолчанию, таким образом, xargs echo является лишним. Почему не делают Вас просто tr '\n' '|' так или иначе? –  tripleee 02.02.2013, 14:54
  • 2
    это - просто быстрый взлом. Я отредактирую его. –  frostschutz 02.02.2013, 15:03

sdiff( 1)-сторона -по -сторона слияния различий файлов

Используйте опцию --output, это интерактивно объединит любые два файла. Вы используете простые команды для выбора изменения или редактирования изменения.

Убедитесь, что установлена ​​переменная окружения EDITOR. Редактором по умолчанию для таких команд, как "eb", обычно является ed, строковый редактор .

EDITOR=nano sdiff -o merged.txt file1.txt file2.txt
8
27.01.2020, 19:45

вы также можете использоватьjoin:

JOIN(1)                            User Commands                            JOIN(1)

NAME
       join - join lines of two files on a common field

SYNOPSIS
       join [OPTION]... FILE1 FILE2

DESCRIPTION
       For each pair of input lines with identical join fields, write a line to
       standard output. The default join field is the first, delimited by blanks.

я нашел это здесь:https://stackoverflow.com/questions/10364455/merge-two-files-by-key-if-exists-in-the-first-file-bash-script

-1
17.04.2020, 07:03

Теги

Похожие вопросы