내 시나리오는 다음과 같습니다
먼저 다음 명령을 사용하여 두 개의 파일을 나란히 생성하십시오 diff
.
diff -y --supress-common-lines file1.txt file2.txt > DiffResult.txt
출력 DiffResult.txt
:
file1.txt file2.txt
This is line A | This is line B
This is line C | This is line D
이제 이 라인에 대해 이야기해보자
This is line A
그리고
This is line B
file1.txt
은 및 의 5행 에 각각 위치합니다 file2.txt
. 그런 다음 적절한 줄 번호를 다음과 같이 연결할 수 있어야 합니다.
원하는 출력 DiffResult.txt
:
file1.txt file2.txt
5 This is line A | 5 This is line B
7 This is line C | 7 This is line D
이 접근 방식을 선택한 이유는 이전에 줄 번호를 생성하면 diff
작은 공백 변경에도 diff
줄과 연결된 줄 번호로 인해 차이가 표시되기 때문입니다.
누구든지 좋은 아이디어가 있나요? 나는 이것이 StackExchange에서 묻는 질문 중 가장 어려운 질문이라고 생각합니다. :D
답변1
이 문제는 필터링된 출력으로 해결될 수 있습니다 diff
. 이 예는 저에게 효과적입니다(diff 출력의 왼쪽/오른쪽 사이의 여백의 위치와 크기는 구현마다 세부 사항이 다를 수 있음).
#!/bin/sh
# $Id: diff-two-column,v 1.2 2016/09/26 20:38:32 tom Exp $
# see http://unix.stackexchange.com/questions/312025/how-to-associate-line-number-from-a-file-to-the-side-by-side-diff-output-result
usage() {
cat >&2 <<EOF
usage: $0 file1 file2
EOF
exit 1
}
[ $# = 2 ] || usage
[ -f "$1" ] || usage
[ -f "$2" ] || usage
width=${COLUMNS:-80}
check=$(stty size|cut -d' ' -f2)
[ -n "$check" ] && width=$check
diff -W $width -y "$1" "$2" | \
expand | \
awk -v width=$width '
BEGIN {
L=0;
R=0;
gutter = width / 2;
half = gutter - 2;
}
{
textL = substr($0, 1, half - 1);
sub("[ ]+$", "", textL); # trim trailing blanks
# The script relies on correctly extracting textM, the gutter:
# if lines differ, textM is " ! "
# if line inserted, textM is " > "
# if line deleted, textM is " < "
# if lines unchanged, textM is " "
textM = substr($0, gutter - 2, 3);
textR = ( length($0) > gutter ) ? substr($0, gutter+1, half) : "";
if ( textM != " > " ) {
L++;
}
if ( textM != " < " ) {
R++;
}
if ( textL != textR ) {
# printf "SHOW %s\n", $0;
# printf "gap \"%s\"\n", textM;
# printf "<<< \"%s\"\n", textL;
# printf ">>> \"%s\"\n", textR;
if ( textL == "" ) {
printf "%5s %-*s %-3s %5d %s\n",
" ", half, textL,
textM,
R, textR;
} else if ( textR == "" ) {
printf "%5d %-*s %-3s %5s %s\n",
L, half, textL,
textM,
" ", textR;
} else {
printf "%5d %-*s %-3s %5d %s\n",
L, half, textL,
textM,
R, textR;
}
} else {
# printf "SKIP %s\n", $0;
}
}
'
줄 번호를 추가할 수 없습니다.앞으로 diff
, 삽입이나 삭제가 있으면 그 지점부터 시작하는 줄 번호가 일치하지 않아 차이가 쓸모없게 되기 때문입니다. 내 스크립트는 awk 스크립트에서 차이의 왼쪽/오른쪽에 있는 줄 번호를 계산합니다.
- 먼저 터미널의 너비를 기준으로 차이의 너비를 결정합니다.
- 예(테스트한 GNU diff 3.2에서)홈통(사용하지 않는 공간) 나란히 있는 차이의 중간에 있습니다. 80열 터미널부터 시작하여 여백 위치를 계산하는 방법을 결정했습니다.
awk
초기화 후 스크립트는 각 행( 의 경우 ) 에서$0
왼쪽(textL
) 및 오른쪽( ) 문자열을 추출textR
하고 해당 문자열이 비어 있는지 테스트합니다(삽입/삭제가 있는 경우 발생함).- 왼쪽/오른쪽 줄이 다른 경우 스크립트는 출력을 재구성
diff
하지만 줄 번호를 추가합니다.
왼쪽에 있는 것을 고려하면
1
2
3
4
This is line A
6
This is line C
123456789.123456789.123456789.123456789.123456789.
yyy
오른쪽에있는 것
1
2
3
4
This is line B
6
This is line D
abcdefghi.abcdefghi.abcdefghi.abcdefghi.abcdefghi.
xxx
(왼쪽 10줄, 오른쪽 9줄) 스크립트가 생성됩니다.
5 This is line A | 5 This is line B
7 This is line C | 7 This is line D
8 123456789.123456789.123456789.1234567 | 8 abcdefghi.abcdefghi.abcdefghi.abcdefg
| 9 xxx
10 yyy <