
我的場景是:
首先使用以下命令並排產生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 <