파일의 줄 번호를 diff 출력 결과 파일과 나란히 연결하는 방법은 무엇입니까?

파일의 줄 번호를 diff 출력 결과 파일과 나란히 연결하는 방법은 무엇입니까?

내 시나리오는 다음과 같습니다

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                                     <        

관련 정보