私のシナリオは次のとおりです。
まず、次のコマンドを使用して2つのファイルを並べて作成します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 <