git
"병합 충돌"이 설명되는 방식 과 유사한 의미를 사용하여 git
기반이 아닌 두 개의 텍스트 파일을 병합 하고 싶습니다 .
file.1
예를 들어, 이름이 비슷 하지만 내용이 동일하지 않은 두 개의 텍스트 파일이 있다고 가정해 보겠습니다 file.2
. 이 두 파일을 다음과 같이 세 번째 파일로 병합하고 싶습니다.
hypothetical-merge-utility file.1 file.2 file.merged
file.merged
다음과 유사한 방식으로 파일 내용과 각 차이점을 나열하는 생성을 원합니다 .
common line 1 ...
common line 2 ...
common line 3 ...
<<<<<<< file.1
something unique from file.1
a second line of something unique from file.1
======= file.2
something unique from file.2
>>>>>>> end of diff
common line 4 ...
common line 5 ...
<<<<<<< file.1
something unique from file.1
======= file.2
something unique from file.2
a second line of something unique from file.2
>>>>>>> end of diff
common line 6 ...
common line 7 ...
... etc. ...
즉, file.1
와 사이의 모든 차이점이 file.2
"병합 충돌"의 표현과 유사하게 나타나기를 원합니다 git
.
<<<<<<<<
, , 및 ========
이외의 구분 기호를 사용해도 상관 없습니다 .>>>>>>>>
Linux에는 텍스트 파일을 병합하는 데 사용할 수 있는 유틸리티가 많이 있다는 것을 알고 있습니다. 그러나 나는오직git
"병합 충돌"이 설명되는 방식과 유사한 방식으로 병합된 데이터를 구체적으로 나타내는 콘텐츠를 찾으세요.
그러한 유틸리티에 대해 아는 사람이 있습니까?
미리 감사드립니다.
고쳐 쓰다: Ed Morton의 다음 질문을 바탕으로 두 테스트 파일의 내용은 다음과 같습니다.
==== 파일.1 ====
common line 1 ...
common line 2 ...
common line 3 ...
something unique from file.1
a second line of something unique from file.1
common line 4 ...
common line 5 ...
something unique from file.1
common line 6 ...
common line 7 ...
==== 파일.2 ====
common line 1 ...
common line 2 ...
common line 3 ...
something unique from file.2
common line 4 ...
common line 5 ...
something unique from file.2
a second line of something unique from file.2
common line 6 ...
common line 7 ...
답변1
노트: 이것이 다소 합리적인 "답변"이라고 생각하지만 이제 더 나은 또 다른 "답변"을 생각해 냈습니다. 아래의 다른 "답변"을 참조하십시오.
이 "답변"의 원본 버전은...
오! 여기에 글을 올리기엔 너무 이르네요. -D
명령줄 옵션을 몰랐 diff
는데 이제 이걸 할 수 있다는 걸 깨달았습니다...
diff -D file.1 file.2 >file.merged
그것은 다음을 생산할 것입니다 file.merged
...
common line 1 ...
common line 2 ...
common line 3 ...
#ifdef file.1
something unique from file.1
a second line of something unique from file.1
#else /* file.1 */
something unique from file.2
#endif /* file.1 */
common line 4 ...
common line 5 ...
#ifdef file.1
something unique from file.1
#else /* file.1 */
something unique from file.2
a second line of something unique from file.2
#endif /* file.1 */
common line 6 ...
common line 7 ...
... etc. ...
내가 감당할 수 있고 #ifdef
, #else
OK , 내가 감당할 수 있는 #endif
것처럼 git
, <<<<<<<<
OK .========
>>>>>>>>
고쳐 쓰다:...방금 이걸 찾았어요: https://stackoverflow.com/questions/16902001/manually-merge-two-files-using-diff
통합 diff 형식을 사용하여 비슷한 작업을 수행할 수 있는 방법도 보여줍니다. 합계의 최대 행 수 보다 큰 인수를 갖는 옵션을 diff
제공 합니다 . 예를 들어...-U
file.1
file.2
diff -U 99999999 file.1 file.2 | tail -n +4 >file.merged
그러면 다음과 같은 결과가 생성됩니다.
common line 1 ...
common line 2 ...
common line 3 ...
+something unique from file.2
-something unique from file.1
-a second line of something unique from file.1
common line 4 ...
common line 5 ...
+something unique from file.2
+a second line of something unique from file.2
-something unique from file.1
common line 6 ...
common line 7 ...
... etc. ...
선은 +
의 고유 데이터를 나타내고 file.2
, -
선은 의 고유 데이터를 나타냅니다 file.1
.
나는 그것 +
과 -
라인을 처리할 수 있습니다.
답변2
출력 형식에 별로 관심이 없는 것처럼 들리지만, 각 파일에서 어떤 줄이 나오는지 또는 어떤 줄이 공통되는지 식별하는 방법을 알고 싶을 뿐입니다. 이건 어때:
$ diff --old-line-format=$'-%l\n' --new-line-format=$'+%l\n' --unchanged-line-format=$'=%l\n' file.1 file.2
=common line 1 ...
=common line 2 ...
=common line 3 ...
-something unique from file.1
-a second line of something unique from file.1
+something unique from file.2
=common line 4 ...
=common line 5 ...
-something unique from file.1
+something unique from file.2
+a second line of something unique from file.2
=common line 6 ...
=common line 7 ...
해당 행에 대한 소스 표시기를 얻기 위해 행의 내용을 테스트해야 하는 솔루션에 주의하세요(예: <<<<<<< file.1
무엇이 고유한지 알려고 하는 경우 file1
- file
해당 문자열과 정확히 동일한 행이 포함되어 있으면 어떻게 됩니까?). 항상 발생합니다. 해당 문자열이 입력에 나타날 가능성이 있는 경우 모든 문자열에 대한 테스트가 실패하므로 각 줄의 고유한 위치를 나타내는 표시입니다. 위와 같이 첫 번째 문자는 항상 줄의 출처를 나타내므로 가능한 파일 내용과 충돌하지 않습니다. git merge 충돌의 정확한 출력 형식을 얻으려면(권장하지 않음) 위 내용을 인쇄하는 간단한 awk 스크립트로 파이프하거나 <<< file
줄의 첫 번째 문자가 원하는 대로 변경될 때 항상 파이프할 수 있습니다. 해당 문자를 삭제하세요.
답변3
diff -D ...
및 와 관련된 첫 번째 "답변"에 원래 게시한 솔루션의 제한으로 인해 Python 모듈을 사용하여 Python으로 솔루션을 작성하기 diff -U ...
로 결정했습니다 .difflib
, , 와 같은 문자열을 포함하는 구분 기호를 git
사용하는데 , 알고 있듯이 원본 텍스트에 이와 같은 문자열이 포함되어 있으면 모호함이 발생할 수 있습니다. 그러나 의 "병합 충돌" 출력에도 동일한 모호성이 존재할 수 있지만 나는 그것에 만족 하고 기꺼이 함께 살기 때문에 내 솔루션의 이러한 모호성에도 만족합니다.<<<<<<<<
========
>>>>>>>>
git
git
출력은 "병합 충돌" 출력과 정확히 동일하지는 않지만 git
내가 원하는 만큼 충분합니다.
첫째, 여기에 Python 프로그램이 있습니다(여기에 게시한 원래 Python 코드를 정리했는데 이것이 정리된 버전입니다). 나는 이 프로그램을 호출합니다 filemerge
...
#!/usr/bin/python3
### Take the diff's between two files and output
### the common and different lines in a manner
### which is very similar to the way that `git`
### depicts merge conflicts.
import sys
sys.dont_write_bytecode = True
import os
from difflib import unified_diff
prog = None
diff_start = '<<<<<<<<'
diff_sep = '========'
diff_end = '>>>>>>>>'
def main():
if len(sys.argv) < 3:
print(f'\nusage: {prog} file1 file2\n')
return 1
file1, file2 = sys.argv[1:3]
data1 = None
data2 = None
missing = []
try:
with open(file1, 'r') as f:
data1 = f.readlines()
except Exception:
missing.append(file1)
try:
with open(file2, 'r') as f:
data2 = f.readlines()
except Exception:
missing.append(file2)
if missing:
print(f'\nnot found: {", ".join(missing)}\n')
return 1
n1 = len(data1)
n2 = len(data2)
max_lines = (n1 + 1) if n1 > n2 else (n2 + 1)
count = 0
state = ''
sep_printed = False
next_file = ''
for line in unified_diff(data1, data2, n=max_lines):
count += 1
if count < 4:
continue
# Every line which is returned by unified_diff()
# is at least 2 characters long. Each of these
# lines starts with either ' ', '+', or '-', and
# each of these lines ends with a newline.
line = line[:-1]
ch0 = line[0]
if ch0 == ' ':
if state:
state = ''
if not sep_printed:
print(f'{diff_sep}{next_file}')
print(diff_end)
sep_printed = False
next_file = ''
elif ch0 == '-':
if state == ch0:
pass
elif state == '+':
print(f'{diff_sep} file={file1}')
sep_printed = True
next_file = ''
else:
print(f'{diff_start} file={file1}')
sep_printed = False
next_file = f' file={file2}'
state = ch0
elif ch0 == '+':
if state == ch0:
pass
elif state == '-':
print(f'{diff_sep} file={file2}')
sep_printed = True
next_file = ''
else:
print(f'{diff_start} file={file2}')
sep_printed = False
next_file = f' file={file1}'
state = ch0
print(line[1:])
if state:
if not sep_printed:
print(f'{diff_sep}{next_file}')
next_file = ''
print(diff_end)
return 0
if __name__ == '__main__':
prog = os.path.basename(sys.argv[0])
sys.exit(main())
이것은 테스트에 사용한 입력 파일입니다. 원래 질문에 게시한 입력 파일과 유사하지만 정확히 동일하지는 않습니다...
file.1
========
common line 1 ...
common line 2 ...
common line 3 ...
something unique from file.1
a second line of something unique from file.1
common line 4 ...
common line 5 ...
something unique from file.1
common line 6 ...
common line 7 ...
penultimate file.1 line
common line 8 ...
file.2
========
common line 1 ...
second line from file.2
common line 2 ...
common line 3 ...
something unique from file.2
common line 4 ...
common line 5 ...
something unique from file.2
a second line of something unique from file.2
common line 6 ...
common line 7 ...
common line 8 ...
이렇게 명령어를 실행하는데...
filemerge file.1 file.2 >file.merged
결과는 다음과 같습니다 file.merged
...
common line 1 ...
<<<<<<<< file=file.2
second line from file.2
======== file=file.1
>>>>>>>>
common line 2 ...
common line 3 ...
<<<<<<<< file=file.1
something unique from file.1
a second line of something unique from file.1
======== file=file.2
something unique from file.2
>>>>>>>>
common line 4 ...
common line 5 ...
<<<<<<<< file=file.1
something unique from file.1
======== file=file.2
something unique from file.2
a second line of something unique from file.2
>>>>>>>>
common line 6 ...
common line 7 ...
<<<<<<<< file=file.1
penultimate file.1 line
======== file=file.2
>>>>>>>>
common line 8 ...
앞서 언급했듯이 이는 Merge Contributes 출력과 정확히 동일한 형식은 아니지만 git
매우 유사하고 나에게는 충분히 유사합니다.