fork download
  1. #! /usr/local/bin/gawk -f
  2.  
  3. # NAME
  4. #
  5. # idiff -- interactive diff
  6. #
  7. # USAGE
  8. #
  9. # idiff file1 file2 -- interactively merge file differences
  10. #
  11. # DESCRIPTION
  12. #
  13. # idiff takes two files file1 and file2, diffs them, and presents
  14. # the difference to the user interactively. At each difference,
  15. # the user may accept the text from file1 by responding <, or
  16. # accept the text from file2 by responding >, or edit the difference
  17. # by responding e (in which case whatever the user saves from the
  18. # editor is entered into the output file), or execute a command
  19. # by typing !cmd, in which case the user must then respond when
  20. # the prompt is repeated. The assembled output with the selected
  21. # differences is placed in file idiff.out.
  22. #
  23. # EXAMPLE
  24. #
  25. # $ cat file1
  26. # This is
  27. # a test
  28. # of
  29. # your
  30. # skill
  31. # and comprehension.
  32. # $ cat file2
  33. # This is
  34. # not a test
  35. # of
  36. # our
  37. # ability.
  38. # $ diff file1 file2
  39. # 2c2
  40. # < a test
  41. # ---
  42. # > not a test
  43. # 4,6d4,5
  44. # < your
  45. # < skill
  46. # < and comprehension.
  47. # ---
  48. # > our
  49. # > ability.
  50. # $ idiff file1 file2
  51. # 2c2
  52. # < a test
  53. # ---
  54. # > not a test
  55. # ? >
  56. # 4,6c4,5
  57. # < your
  58. # < skill
  59. # < and comprehension.
  60. # ---
  61. # > our
  62. # > ability.
  63. # ? <
  64. # $ cat idiff.out
  65. # This is
  66. # not a test
  67. # of
  68. # your
  69. # skill
  70. # and comprehension.\014
  71.  
  72. BEGIN {
  73.  
  74. ed = ENVIRON["EDITOR"]; if (ed == "") { ed = "ed" }
  75. outfile = "idiff.out"; tempfile = "idiff.tmp"; diffile = "idiff.dif"
  76. file1 = ARGV[1]; file2 = ARGV[2]; ARGV[1] = ARGV[2] = ""
  77. system("diff " file1 " " file2 " > " diffile)
  78. nf1 = nf2 = 0
  79.  
  80. while (getline difline < diffile > 0) {
  81.  
  82. cmd = substr(difline, match(difline, /[acd]/), 1)
  83. split(difline, linenums, cmd)
  84. split(linenums[1], ones, ","); split(linenums[2], twos, ",")
  85. from1 = ones[1]; to1 = ones[2] > 0 ? ones[2] : ones[1]
  86. from2 = twos[1]; to2 = twos[2] > 0 ? twos[2] : twos[1]
  87. nlines = to1-from1 + to2-from2 + 1
  88. if (cmd == "a") { from1++ }
  89. else if (cmd == "c") { nlines += 2 }
  90. else if (cmd == "d") { from2++ }
  91.  
  92. print difline
  93. while (nlines-- > 0) { getline difline < diffile; print difline }
  94.  
  95. do {
  96. printf("? "); getline buf
  97. if (substr(buf, 1, 1) == ">") {
  98. nskip(file1, to1-nf1); ncopy(file2, to2-nf2, outfile) }
  99. else if (substr(buf, 1, 1) == "<") {
  100. nskip(file2, to2-nf2); ncopy(file1, to1-nf1, outfile) }
  101. else if (substr(buf, 1, 1) == "e") {
  102. ncopy(file1, from1-1-nf1, outfile)
  103. nskip(file2, from2-1-nf2)
  104. ncopy(file1, to1+1-from1, tempfile)
  105. print "---" > tempfile
  106. ncopy(file2, to2+1-from2, tempfile)
  107. close(tempfile)
  108. system(ed " " tempfile)
  109. ncopy(tempfile, -1, outfile)
  110. close(tempfile) }
  111. else if (substr(buf, 1, 1) == "!") {
  112. system(substr(buf, 2)); print "!" }
  113. else { print "Enter < or > or e or !cmd" }
  114.  
  115. } while (substr(buf, 1, 1) !~ /[><e]/)
  116. nf1 = to1; nf2 = to2
  117. }
  118. system("rm " tempfile " " diffile)
  119. }
  120.  
  121. function nskip(fin, n, junk) {
  122. while (n-- != 0) { getline junk < fin } }
  123. function ncopy(fin, n, fout, line) {
  124. while ((n-- != 0) && (getline line < fin > 0)) { print line > fout } }
Not running #stdin #stdout 0s 0KB
stdin
Standard input is empty
stdout
Standard output is empty