Как запретить GNU diff группировать строки для патчей? - PullRequest
1 голос
/ 26 мая 2020

Я унаследовал от кого-то еще поддержку двух версий набора файлов html, одна большая с переводом, другая короче без перевода. Тело коротких файлов и длинного файла различается только строками, содержащими перевод. Но есть также определенное c содержимое, которое не является обычным где-то в этих файлах, и его нужно поддерживать нетронутым.

коротко. html

Salve<br/>
Quomodo te habes?<br/>
Some lines specific to short.html

long. html

Salve<br/>
Hello!<br/>
Quomodo te habes?<br/>
How do you do?<br/>
Some other lines specific to long.html

Я использую для редактирования более короткого, и, чтобы не повторять эту работу дважды, я смотрю на различия с GNU diff, чтобы создать patch, чтобы применить те же исправления к большему файлу.

diff short.html.orig short.html > short.diff
patch -z .orig long.html short.diff

Это сработало как прелесть, потому что patch достаточно умен, чтобы перепрыгнуть через мусор и найти место для исправления, пока мне не пришлось исправлять соседние строки в коротких файлах.

В этом случае вывод команды diff выглядит так:

1,2c1,2
< Salve<br/>
< Quomodo te habes?<br/>
---
> Salvete<br/>
> Quomodo vos habetis?<br/>

и патч отклоняется, потому что, как я предполагаю, patch не находит ни одного блока две строки, содержащие Salve... и Quomodo... для замены в длинных. html, поскольку эти две строки больше не смежны в более длинной версии, где перевод вставляется после каждой строки. Пока патчи применяются построчно, он отлично работает, но когда патчи сгруппированы в блок (они называют кусок), он больше не работает.

Мой вопрос: как мне предотвратить diff от группировки строк, подлежащих исправлению, в блоки, чтобы исправления применялись построчно?

Без лишних слов, я sh заменяю вывод команды diff на это:

1c1
< Salve<br/>
---
> Salvete<br/>
2c2
< Quomodo te habes?<br/>
---
> Quomodo vos habetis?<br/>

1 Ответ

2 голосов
/ 27 мая 2020

Я нашел решение моей проблемы, скорее обходной путь, при котором я не меняю поведение diff. С помощью AWK можно обрабатывать его вывод, чтобы разрезать блоки, имеющие несколько строк, на фрагменты одной строки:

diffungroup

awk -F ',|c' ' # process lines as "3,4c3,4" and following lines
  /[0-9]+,[0-9]+c[0-9]+,[0-9]+/ {
    ss = $1; se = $2; ds = $3; de = $4; 
    for (i = ss; i <= se; i++) {
      getline
      a[i] = $0
    }
    getline # skip "---"    
    i = ss
    for (j = ds; j <= de; j++) {
      print i "c" j
      print a[i++]
      print "---"
      getline
      print $0
    } 
    next 
  }
  { print }
' "$@"

Он преобразует вывод diff например:

1,2c1,2
< Salve<br/>
< Quomodo te habes?<br/>
---
> Salvete<br/>
> Quomodo vos habetis?<br/>

в:

1c1
< Salve<br/>
---
> Salvete<br/>
2c2
< Quomodo te habes?<br/>
---
> Quomodo vos habetis?<br/>

В контексте, описанном в вопросе выше, я вызываю его следующим образом:

diff short.html.orig short.html > short.diff
./diffungroup short.diff > long.diff
patch -z .orig long.html long.diff

И, как я уже сказал выше, работает как шарм.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...