it-swarm-id.com

beda dalam satu garis

Saya punya beberapa dump sql yang saya cari perbedaannya. diff jelas dapat menunjukkan kepada saya perbedaan antara dua baris, tetapi saya membuat diri saya gila mencoba untuk menemukan nilai mana dalam daftar panjang nilai yang dipisahkan koma sebenarnya yang menyebabkan garis menjadi berbeda.

Alat apa yang dapat saya gunakan untuk menunjukkan perbedaan karakter yang tepat antara dua baris dalam file tertentu?

120
user394

Ada wdiff , beda kata-kata untuk itu.

Di desktop, meld dapat menyorot perbedaan dalam satu baris untuk Anda.

96
alex

Hanya metode lain menggunakan git-diff:

git diff -U0 --Word-diff --no-index -- foo bar | grep -v ^@@

grep -v jika tidak tertarik pada posisi diffs.

31
Deepak

Saya telah menggunakan vimdiff untuk ini.

Ini tangkapan layar (bukan milikku) menunjukkan satu atau dua perbedaan karakter kecil yang menonjol dengan cukup baik. A tutorial cepat juga .

24
Mark McKinstry

Ini adalah metode "..hair dari anjing yang menggigitmu" ...
diff membuat Anda sampai pada titik ini; gunakan untuk membawa Anda lebih jauh ...

Ini adalah output dari penggunaan pasangan garis sampel ... menunjukkan TAB

Paris in the     spring 
Paris in the the spring 
             vvvv      ^

A ca t on a hot tin roof.
a cant on a hot  in roof 
║   v           ^       ^

the quikc brown box jupps ober the laze dogs 
The☻qui ckbrown fox jumps over the lazy dogs 
║  ║   ^ ║      ║     ║    ║          ║     ^

Ini skripnya .. Anda hanya perlu menemukan pasangan garisnya entah bagaimana .. (Saya hanya menggunakan diff sekali (dua kali?) Sebelum hari ini, jadi saya tidak tahu banyak pilihannya, dan memilah opsi untuk ini script sudah cukup untuk saya, untuk satu hari :) .. Saya pikir itu harus cukup sederhana, tetapi saya harus istirahat kopi ....

#
# Name: hair-of-the-diff
# Note: This script hasn't been extensively tested, so beware the alpha bug :) 
#   
# Brief: Uses 'diff' to identify the differences between two lines of text
#        $1 is a filename of a file which contains line pairs to be processed
#
#        If $1 is null "", then the sample pairs are processed (see below: Paris in the spring 
#          
# ║ = changed character
# ^ = exists if first line, but not in second 
# v = exists if second line, but not in first

bname="$(basename "$0")"
workd="/tmp/$USER/$bname"; [[ ! -d "$workd" ]] && mkdir -p "$workd"

# Use $1 as the input file-name, else use this Test-data
# Note: this test loop expands \t \n etc ...(my editor auto converts \t to spaces) 
if [[ "$1" == '' ]] ;then
  ifile="$workd/ifile"
{ while IFS= read -r line ;do echo -e "$line" ;done <<EOF
Paris in the spring 
Paris in the the spring
A cat on a hot tin roof.
a cant on a hot in roof
the quikc brown box jupps ober the laze dogs 
The\tquickbrown fox jumps over the lazy dogs
EOF
} >"$ifile"
else
  ifile="$1"
fi
#
[[ -f "$ifile" ]] || { echo "ERROR: Input file NOT found:" ;echo "$ifile" ;exit 1 ; }
#  
# Check for balanced pairs of lines
ilct=$(<"$ifile" wc -l)
((ilct%2==0)) || { echo "ERROR: Uneven number of lines ($ilct) in the input." ;exit 2 ; }
#
ifs="$IFS" ;IFS=$'\n' ;set -f
ix=0 ;left=0 ;right=1
while IFS= read -r line ;do
  pair[ix]="$line" ;((ix++))
  if ((ix%2==0)) ;then
    # Change \x20 to \x02 to simplify parsing diff's output,
    #+   then change \x02 back to \x20 for the final output. 
    # Change \x09 to \x01 to simplify parsing diff's output, 
    #+   then change \x01 into ☻ U+263B (BLACK SMILING FACE) 
    #+   to the keep the final display columns in line. 
    #+   '☻' is hopefully unique and obvious enough (otherwise change it) 
    diff --text -yt -W 19  \
         <(echo "${pair[0]}" |sed -e "s/\x09/\x01/g" -e "s/\x20/\x02/g" -e "s/\(.\)/\1\n/g") \
         <(echo "${pair[1]}" |sed -e "s/\x09/\x01/g" -e "s/\x20/\x02/g" -e "s/\(.\)/\1\n/g") \
     |sed -e "s/\x01/☻/g" -e "s/\x02/ /g" \
     |sed -e "s/^\(.\) *\x3C$/\1 \x3C  /g" \
     |sed -n "s/\(.\) *\(.\) \(.\)$/\1\2\3/p" \
     >"$workd/out"
     # (gedit "$workd/out" &)
     <"$workd/out" sed -e "s/^\(.\)..$/\1/" |tr -d '\n' ;echo
     <"$workd/out" sed -e "s/^..\(.\)$/\1/" |tr -d '\n' ;echo
     <"$workd/out" sed -e "s/^.\(.\).$/\1/" -e "s/|/║/" -e "s/</^/" -e "s/>/v/" |tr -d '\n' ;echo
    echo
    ((ix=0))
  fi
done <"$ifile"
IFS="$ifs" ;set +f
exit
#
6
Peter.O

wdiff sebenarnya adalah metode yang sangat lama membandingkan file Word-by-Word. Ini berfungsi dengan memformat ulang file, kemudian menggunakan diff untuk menemukan perbedaan dan meneruskannya kembali. Saya sendiri menyarankan untuk menambahkan konteks, sehingga dibandingkan dengan kata per kata, ia melakukannya dengan setiap kata dikelilingi oleh kata-kata 'konteks' lainnya. Itu memungkinkan diff untuk menyinkronkan dirinya sendiri pada bagian-bagian umum dalam file jauh lebih baik, terutama ketika file sebagian besar berbeda dengan hanya beberapa blok kata-kata umum. Misalnya ketika membandingkan teks untuk plagiarisme, atau digunakan kembali.

dwdiff kemudian dibuat dari wdiff. Tapi dwdiff menggunakan fungsi pemformatan ulang teks tersebut untuk efek yang baik dalam dwfilter. Ini adalah pengembangan yang luar biasa - ini artinya Anda dapat memformat ulang satu teks untuk mencocokkan yang lain, dan kemudian membandingkannya dengan menggunakan penampil gambar grafik baris per baris. Misalnya, menggunakannya dengan ...

dwfilter file1 file2 diffuse -w

Ini memformat ulang file1 ke format file2 dan memberikannya kepada diffuse untuk perbandingan visual. file2 tidak dimodifikasi, sehingga Anda dapat mengedit dan menggabungkan perbedaan Word ke dalamnya secara langsung dalam diffuse. Jika Anda ingin mengedit file1, Anda dapat menambahkan -r untuk membalikkan file mana yang diformat ulang. Cobalah dan Anda akan menemukannya sangat kuat!

Preferensi saya untuk perbedaan grafis (ditunjukkan di atas) adalah diffuse karena terasa jauh lebih bersih dan lebih bermanfaat. Juga itu adalah program mandiri python, yang artinya mudah untuk menginstal dan mendistribusikan ke sistem UNIX lainnya.

Perbedaan grafis lain tampaknya memiliki banyak ketergantungan, tetapi juga dapat digunakan (pilihan Anda). Ini termasuk kdiff3 atau xxdiff .

5
anthony

Menggunakan @ Peter.O's solusi sebagai dasar saya menulis ulang untuk membuat sejumlah perubahan.

enter image description here

  • Hanya mencetak setiap baris sekali, menggunakan warna untuk menunjukkan perbedaan.
  • Itu tidak menulis file temp, memipiskan semuanya.
  • Anda dapat memberikan dua nama file dan itu akan membandingkan baris yang sesuai di setiap file. ./hairOfTheDiff.sh file1.txt file2.txt
  • Jika tidak, jika Anda menggunakan format asli (satu file dengan setiap baris kedua perlu dibandingkan dengan yang sebelumnya), Anda sekarang dapat memasukkannya ke dalam file, tidak perlu ada file untuk dibaca. Lihatlah demo di sumber; ini mungkin membuka pintu untuk pemipaan agar tidak perlu file untuk dua input terpisah juga, menggunakan paste dan beberapa file-deskriptor.

Tidak ada highlight artinya karakter ada di kedua baris, highlight artinya ada di yang pertama, dan merah berarti di yang kedua.

Warna dapat diubah melalui variabel di bagian atas skrip dan Anda bahkan dapat melepaskan warna sepenuhnya dengan menggunakan karakter normal untuk mengekspresikan perbedaan.

#!/bin/bash

same='-' #unchanged
up='△' #exists in first line, but not in second 
down='▽' #exists in second line, but not in first
reset=''

reset=$'\e[0m'
same=$reset
up=$reset$'\e[1m\e[7m'
down=$reset$'\e[1m\e[7m\e[31m'

timeout=1


if [[ "$1" != '' ]]
then
    paste -d'\n' "$1" "$2" | "$0"
    exit
fi

function demo {
    "$0" <<EOF
Paris in the spring 
Paris in the the spring
A cat on a hot tin roof.
a cant on a hot in roof
the quikc brown box jupps ober the laze dogs 
The quickbrown fox jumps over the lazy dogs
EOF
}

# Change \x20 to \x02 to simplify parsing diff's output,
#+   then change \x02 back to \x20 for the final output. 
# Change \x09 to \x01 to simplify parsing diff's output, 
#+   then change \x01 into → U+1F143 (Squared Latin Capital Letter T)
function input {
    sed \
        -e "s/\x09/\x01/g" \
        -e "s/\x20/\x02/g" \
        -e "s/\(.\)/\1\n/g"
}
function output {
    sed -n \
        -e "s/\x01/→/g" \
        -e "s/\x02/ /g" \
        -e "s/^\(.\) *\x3C$/\1 \x3C  /g" \
        -e "s/\(.\) *\(.\) \(.\)$/\1\2\3/p"
}

ifs="$IFS"
IFS=$'\n'
demo=true

while IFS= read -t "$timeout" -r a
do
    demo=false
    IFS= read -t "$timeout" -r b
    if [[ $? -ne 0 ]]
    then
        echo 'No corresponding line to compare with' > /dev/stderr
        exit 1
    fi

    diff --text -yt -W 19  \
        <(echo "$a" | input) \
        <(echo "$b" | input) \
    | \
    output | \
    {
        type=''
        buf=''
        while read -r line
        do
            if [[ "${line:1:1}" != "$type" ]]
            then
                if [[ "$type" = '|' ]]
                then
                    type='>'
                    echo -n "$down$buf"
                    buf=''
                fi

                if [[ "${line:1:1}" != "$type" ]]
                then
                    type="${line:1:1}"

                    echo -n "$type" \
                        | sed \
                            -e "s/[<|]/$up/" \
                            -e "s/>/$down/" \
                            -e "s/ /$same/"
                fi
            fi

            case "$type" in
            '|')
                buf="$buf${line:2:1}"
                echo -n "${line:0:1}"
                ;;
            '>')
                echo -n "${line:2:1}"
                ;;
            *)
                echo -n "${line:0:1}"
                ;;
            esac
        done

        if [[ "$type" = '|' ]]
        then
            echo -n "$down$buf"
        fi
    }

    echo -e "$reset"
done

IFS="$ifs"

if $demo
then
    demo
fi
4
Hashbrown

Berikut ini satu kalimat sederhana:

diff -y <(cat a.txt | sed -e 's/,/\n/g') <(cat b.txt | sed -e 's/,/\n/g')

Idenya adalah untuk mengganti koma (atau pembatas mana pun yang ingin Anda gunakan) dengan baris baru menggunakan sed. diff lalu mengurus sisanya.

3
user82160
  • xxdiff: Alat lain adalah xxdiff (GUI), yang harus diinstal terlebih dahulu.
  • spreadsheet: Untuk data database, spreadsheet dari .csv mudah dibuat, dan formula (A7==K7) ? "" : "diff" atau yang serupa disisipkan, dan disalin-tempel.
2
user unknown

Jika saya membaca pertanyaan Anda dengan benar, saya menggunakan diff -y untuk hal semacam ini.

Itu membuat membandingkan perbandingan berdampingan jauh lebih mudah untuk menemukan garis mana yang melempar perbedaan.

1
rfelsburg

Pada baris perintah, saya akan memastikan saya menambahkan baris baru yang bijaksana sebelum membandingkan file. Anda dapat menggunakan sed, awk, Perl atau apa pun untuk menambahkan jeda baris dengan cara sistematis - pastikan untuk tidak menambahkan terlalu banyak.

Tapi saya menemukan yang terbaik adalah menggunakan vim karena menyoroti perbedaan Word. vim baik jika tidak terlalu banyak perbedaan dan perbedaannya sederhana.

1
asoundmove

Saya memiliki masalah yang sama dan menyelesaikannya dengan PHP Fine Diff , alat online yang memungkinkan Anda menentukan rincian. Saya tahu ini bukan alat * nix secara teknis, tetapi saya tidak benar-benar ingin mengunduh program hanya untuk melakukan satu kali, perbedaan level karakter.

1
pillravi

kdiff menjadi penampil diff GUI standar di Linux. Ini mirip dengan xxdiff , tapi saya pikir kdiff3 lebih baik. Itu melakukan banyak hal dengan baik, termasuk permintaan Anda untuk menunjukkan "perbedaan karakter yang tepat antara dua baris dalam file tertentu".

1
Faheem Mitha