O problema pode ser resolvido filtrando a saída de diff
. Este exemplo funciona para mim (embora o posicionamento e o tamanho da medianiz entre os lados esquerdo e direito da saída do diff sejam provavelmente um detalhe que difere entre as implementações):
#!/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;
}
}
'
Não é possível adicionar números de linha antes diff
, porque se houver inserções ou exclusões, os números de linha que começam nesse ponto não corresponderão, fazendo com que as diferenças não sejam úteis. Meu script calcula os números de linha para os lados esquerdo / direito da diferença no script awk:
- Decide primeiro a largura para fazer o diff, com base na largura do terminal.
- Existe (no GNU diff 3.2 que testei) um gutter (espaço não utilizado) no meio das diferenças lado-a-lado. Começando com um terminal de 80 colunas, determinei uma maneira de calcular a posição da calha.
- Após a inicialização, o script extrai de cada linha (em
awk
, isso é$0
) as cadeias esquerda (textL
) e direita (textR
) e testa se estão vazias (o que aconteceria se houvesse uma inserção / exclusão). - Se as linhas esquerda / direita forem diferentes, o script reconstruirá a saída
diff
, mas adicionando os números de linha.
Dado isso à esquerda
1
2
3
4
This is line A
6
This is line C
123456789.123456789.123456789.123456789.123456789.
yyy
e isso à direita
1
2
3
4
This is line B
6
This is line D
abcdefghi.abcdefghi.abcdefghi.abcdefghi.abcdefghi.
xxx
(10 linhas à esquerda, 9 à direita), esse script produz
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 <