比较文件命令之diff,patch,vimdiff,cmp

diff

比较两个文件之间的区别

[20:34:32 root@C8-3-55 ~]#diff --help
用法:diff [选项]... 文件们
逐行比较<文件们>。

长选项的必需参数也是相应短选项的必需参数。
      --normal                  以正常的 diff 方式输出 (默认)
  -q, --brief                   只有在文件不同时报告
  -s, --report-identical-files  当两个一样时仍然显示结果
  -c, -C NUM, --context[=NUM]   output NUM (default 3) lines of copied context
  -u, -U 数量, --unified[=数量] 输出 <数量>(默认为 3)行一致化上下文
  -e, --ed                      以 ed script 方式输出
  -n, --rcs                     以 RCS diff 格式输出
  -y, --side-by-side            output in two columns
  -W, --width=数量              每行显示最多 <数量>(默认 130)个字符
      --left-column             当有两行相同时只显示左边栏的一行
      --suppress-common-lines   当有两行相同时不显示

  -p, --show-c-function         show which C function each change is in
  -F, --show-function-line=RE   show the most recent line matching RE
      --label LABEL             use LABEL instead of file name and timestamp
                                  (can be repeated)

  -t, --expand-tabs             将输出中的 tab 转换成空格
  -T, --initial-tab             每行先加上 tab 字符,使 tab 字符可以对齐
      --tabsize=数字           TAB 格的宽度,默认为 8 个打印列宽
      --suppress-blank-empty    suppress space or tab before empty output lines
  -l, --paginate                将输出送至 “pr” 指令来分页

  -r, --recursive                 连同所有子目录一起比较
      --no-dereference            don't follow symbolic links
  -N, --new-file                  不存在的文件以空文件方式处理
      --unidirectional-new-file   若第一文件不存在,以空文件处理
      --ignore-file-name-case     忽略文件名大小写的区别
      --no-ignore-file-name-case  不忽略文件名大小写的区别
  -x, --exclude=模式              排除匹配 <模式> 的文件
  -X, --exclude-from=文件         排除所有匹配在<文件>中列出的模式的文件
  -S, --starting-file=文件        当比较目录時,由<文件>开始比较
      --from-file=文件1           将<文件1>和操作数中的所有文件/目录作比较;
                                    <文件1>可以是目录
      --to-file=文件2             将操作数中的所有文件/目录和<文件2>作比较;
                                    <文件2>可以是目录

  -i, --ignore-case               忽略文件内容大小写的区别
  -E, --ignore-tab-expansion      忽略由制表符宽度造成的差异
  -Z, --ignore-trailing-space     忽略每行末端的空格
  -b, --ignore-space-change       忽略由空格数不同造成的差异
  -w, --ignore-all-space          忽略所有空格
  -B, --ignore-blank-lines        忽略任何因空行而造成的差异
  -I, --ignore-matching-lines=正则 若某行完全匹配 <正则>,则忽略由该行造成的差异

  -a, --text                      所有文件都以文本方式处理
      --strip-trailing-cr         去除输入内容每行末端的回车(CR)字符

  -D, --ifdef=名称                输出的内容以 ‘#ifdef <名称>’ 方式标明差异
      --GTYPE-group-format=GFMT   以 GFMT 格式处理 GTYPE 输入行组
      --line-format=LFMT          以 LFMT 格式处理每一行资料
      --LTYPE-line-format=LFMT    以 LFMT 格式处理 LTYPE 输入的行
    These format options provide fine-grained control over the output
      of diff, generalizing -D/--ifdef.
    LTYPE 可以是 “old”、“new” 或 “unchanged”。GTYPE 可以是 LTYPE 的选择
    或是 “changed”。
  (仅)GFMT 可包括:
      %<  该组中每行属于<文件1>的差异
      %>  该组中每行属于<文件2>的差异
      %=  该组中同时在<文件1>和<文件2>出现的每一行
      %[-][宽度][.[精确度]]{doxX}字符  以 printf 格式表示该<字符>代表的内容
        大写<字符>表示属于新的文件,小写表示属于旧的文件。<字符>的意义如下:
          F  行组中第一行的行号
          L  行组中最后一行的行号
          N  行数 ( =L-F+1 )
          E  F-1
          M  L+1
      %(A=B?T:E)  如果 A 等于 B 那么 T 否则 E
  (仅)LFMT 可包括:
      %L  该行的内容
      %l  该行的内容,但不包括结束的换行符
      %[-][宽度][.[精确度]]{doxX}n  以 printf 格式表示的输入行号
    GFMT 或 LFMT 都可包括:
      %%        %
      %c'C'     单个字符 C
      %c'OOO'  八进制码 OOO 所代表的字符
      C         字符 C(处上述转义外的其他字符代表它们自身)

  -d, --minimal            尽可能找出最小的差异。
      --horizon-lines=数量 保持<数量>行的一致前后缀
      --speed-large-files  假设文件十分大而且文件中含有许多微小的差异
      --color[=WHEN]       colorize the output; WHEN can be 'never', 'always',
                             or 'auto' (the default)
      --palette=PALETTE    the colors to use when --color is active; PALETTE is
                             a colon-separated list of terminfo capabilities

      --help               显示此帮助信息并退出
  -v, --version            输出版本信息并退出

FILES are 'FILE1 FILE2' or 'DIR1 DIR2' or 'DIR FILE' or 'FILE DIR'.
如果使用 --from-file 或 --to-file 选项,<文件名> 的格式则不受限制。
如果 FILE 是 “-”,则由标准输入读取内容。
如果输入相同,则退出状态为 0;1 表示输入不同;2 表示有错误产生。
  • 显示了两个文件的不同之处
[20:38:55 root@C8-3-55 ~]#diff passwd.bak1 passwd.bak2
139a140
> VRkQaIfhKJ
 文件尾没有换行符
  • 使用 -u 参数显示详细的区别
[20:39:46 root@C8-3-55 ~]#diff  -u passwd.bak1 passwd.bak2
--- passwd.bak1 2021-03-07 09:20:50.693195530 -0500
+++ passwd.bak2 2021-03-07 09:21:12.219262652 -0500
@@ -137,3 +137,4 @@
 user98:x:8988:8988::/home/user98:/bin/bash
 user99:x:8989:8989::/home/user99:/bin/bash
 user100:x:8990:8990::/home/user100:/bin/bash
+VRkQaIfhKJ
 文件尾没有换行符

利用diff命令保存两文件的不同,从而通过一个文件重新生成另一个文件

[20:39:46 root@C8-3-55 ~]#diff  -u passwd.bak1 passwd.bak2
--- passwd.bak1 2021-03-07 09:20:50.693195530 -0500
+++ passwd.bak2 2021-03-07 09:21:12.219262652 -0500
@@ -137,3 +137,4 @@
 user98:x:8988:8988::/home/user98:/bin/bash
 user99:x:8989:8989::/home/user99:/bin/bash
 user100:x:8990:8990::/home/user100:/bin/bash
+VRkQaIfhKJ
 文件尾没有换行符
[20:40:52 root@C8-3-55 ~]#diff passwd.bak1 passwd.bak2 >pwd.patch # 比较两个文件的不同并将结果输出到文件
[20:45:29 root@C8-3-55 ~]#rm -f passwd.bak2 # 删掉bak2
[20:45:46 root@C8-3-55 ~]#patch -b passwd.bak1 pwd.patch # 使用patch -b命令配合之前生成的差异文件pwd.patch修补passed.bak1
patching file passwd.bak1 ## 显示修补完成

[20:49:03 root@C8-3-55 ~]#diff -u passwd.bak1 passwd.bak1.orig # 查看修补完成文件和备份文件差异,orig为自动生成
--- passwd.bak1 2021-03-07 20:47:47.749139284 -0500 ## 生成的passwd.bak1为原来的passwd.bak2
+++ passwd.bak1.orig    2021-03-07 09:20:50.693195530 -0500  ## 生成的passwd.bak1.orig 为原来的passwd.bak1
@@ -137,4 +137,3 @@
 user98:x:8988:8988::/home/user98:/bin/bash
 user99:x:8989:8989::/home/user99:/bin/bash
 user100:x:8990:8990::/home/user100:/bin/bash
-VRkQaIfhKJ
 文件尾没有换行符

[20:49:41 root@C8-3-55 ~]#diff -u passwd.bak1.orig passwd.bak1 ## 和之前比较bak1和bak2的结果一直
--- passwd.bak1.orig    2021-03-07 09:20:50.693195530 -0500
+++ passwd.bak1 2021-03-07 20:47:47.749139284 -0500
@@ -137,3 +137,4 @@
 user98:x:8988:8988::/home/user98:/bin/bash
 user99:x:8989:8989::/home/user99:/bin/bash
 user100:x:8990:8990::/home/user100:/bin/bash
+VRkQaIfhKJ
 文件尾没有换行符

patch

复制在其他文件中进行的变更,可以理解为按照差异文件来修补一个文件变成另一个文件

[20:34:37 root@C8-3-55 ~]#patch --help
Usage: patch [OPTION]... [ORIGFILE [PATCHFILE]]

Input options:

  -p NUM  --strip=NUM  Strip NUM leading components from file names.
  -F LINES  --fuzz LINES  Set the fuzz factor to LINES for inexact matching.
  -l  --ignore-whitespace  Ignore white space changes between patch and input.

  -c  --context  Interpret the patch as a context difference.
  -e  --ed  Interpret the patch as an ed script.
  -n  --normal  Interpret the patch as a normal difference.
  -u  --unified  Interpret the patch as a unified difference.

  -N  --forward  Ignore patches that appear to be reversed or already applied.
  -R  --reverse  Assume patches were created with old and new files swapped.

  -i PATCHFILE  --input=PATCHFILE  Read patch from PATCHFILE instead of stdin.

Output options:

  -o FILE  --output=FILE  Output patched files to FILE.
  -r FILE  --reject-file=FILE  Output rejects to FILE.

  -D NAME  --ifdef=NAME  Make merged if-then-else output using NAME.
  --merge  Merge using conflict markers instead of creating reject files.
  -E  --remove-empty-files  Remove output files that are empty after patching.

  -Z  --set-utc  Set times of patched files, assuming diff uses UTC (GMT).
  -T  --set-time  Likewise, assuming local time.

  --quoting-style=WORD   output file names using quoting style WORD.
    Valid WORDs are: literal, shell, shell-always, c, escape.
    Default is taken from QUOTING_STYLE env variable, or 'shell' if unset.

Backup and version control options:

  -b  --backup  Back up the original contents of each file.
  --backup-if-mismatch  Back up if the patch does not match exactly.
  --no-backup-if-mismatch  Back up mismatches only if otherwise requested.

  -V STYLE  --version-control=STYLE  Use STYLE version control.
        STYLE is either 'simple', 'numbered', or 'existing'.
  -B PREFIX  --prefix=PREFIX  Prepend PREFIX to backup file names.
  -Y PREFIX  --basename-prefix=PREFIX  Prepend PREFIX to backup file basenames.
  -z SUFFIX  --suffix=SUFFIX  Append SUFFIX to backup file names.

  -g NUM  --get=NUM  Get files from RCS etc. if positive; ask if negative.

Miscellaneous options:

  -t  --batch  Ask no questions; skip bad-Prereq patches; assume reversed.
  -f  --force  Like -t, but ignore bad-Prereq patches, and assume unreversed.
  -s  --quiet  --silent  Work silently unless an error occurs.
  --verbose  Output extra information about the work being done.
  --dry-run  Do not actually change any files; just print what would happen.
  --posix  Conform to the POSIX standard.

  -d DIR  --directory=DIR  Change the working directory to DIR first.
  --reject-format=FORMAT  Create 'context' or 'unified' rejects.
  --binary  Read and write data in binary mode.
  --read-only=BEHAVIOR  How to handle read-only input files: 'ignore' that they
                        are read-only, 'warn' (default), or 'fail'.

  -v  --version  Output version info.
  --help  Output this help.

Report bugs to <bug-patch@gnu.org>.

vimdiff

vimdiff通过双窗口显示,可以直观的比较两个文件

  • vimdiff其实是vim的软链接
[21:06:31 root@C8-3-55 ~]#ll `which vimdiff`
lrwxrwxrwx. 1 root root 3 11月 11 2019 /usr/bin/vimdiff -> vim
  • vimdiff等同于 vim -d
[20:35:37 root@C8-3-55 ~]#vimdiff --help
VIM - Vi IMproved 8.0 (2016 Sep 12, compiled Nov 11 2019 19:08:24)

用法: vim [参数] [文件 ..]       编辑指定的文件
  或: vim [参数] -               从标准输入(stdin)读取文本
  或: vim [参数] -t tag          编辑 tag 定义处的文件
  或: vim [参数] -q [errorfile]  编辑第一个出错处的文件

参数:
   --                   在这以后只有文件名
   -v                   Vi 模式 (同 "vi")
   -e                   Ex 模式 (同 "ex")
   -E                   Improved Ex mode
   -s                   安静(批处理)模式 (只能与 "ex" 一起使用)
   -d                   Diff 模式 (同 "vimdiff")
   -y                   容易模式 (同 "evim",无模式)
   -R                   只读模式 (同 "view")
   -Z                   限制模式 (同 "rvim")
   -m                   不可修改(写入文件)
   -M                   文本不可修改
   -b                   二进制模式
   -l                   Lisp 模式
   -C                   兼容传统的 Vi: 'compatible'
   -N                   不完全兼容传统的 Vi: 'nocompatible'
   -V[N][fname]         Be verbose [level N] [log messages to fname]
   -D                   调试模式
   -n                   不使用交换文件,只使用内存
   -r                   列出交换文件并退出
   -r (跟文件名)                恢复崩溃的会话
   -L                   同 -r
   -A                   以 Arabic 模式启动
   -H                   以 Hebrew 模式启动
   -F                   以 Farsi 模式启动
   -T <terminal>        设定终端类型为 <terminal>
   --not-a-term         Skip warning for input/output not being a terminal
   --ttyfail            Exit if input or output is not a terminal
   -u <vimrc>           使用 <vimrc> 替代任何 .vimrc
   --noplugin           不加载 plugin 脚本
   -P[N]                打开 N 个标签页 (默认值: 每个文件一个)
   -o[N]                打开 N 个窗口 (默认值: 每个文件一个)
   -O[N]                同 -o 但垂直分割
   +                    启动后跳到文件末尾
   +<lnum>              启动后跳到第 <lnum> 行
   --cmd <command>      加载任何 vimrc 文件前执行 <command>
   -c <command>         加载第一个文件后执行 <command>
   -S <session>         加载第一个文件后执行文件 <session>
   -s <scriptin>        从文件 <scriptin> 读入正常模式的命令
   -w <scriptout>       将所有输入的命令追加到文件 <scriptout>
   -W <scriptout>       将所有输入的命令写入到文件 <scriptout>
   -x                   编辑加密的文件
   --startuptime <file> Write startup timing messages to <file>
   -i <viminfo>         使用 <viminfo> 取代 .viminfo
   --clean              'nocompatible', Vim defaults, no plugins, no viminfo
   -h  或  --help       打印帮助(本信息)并退出
   --version            打印版本信息并退出

cmp

cmp可以用来比较两个二进制文件

[21:12:34 root@C8-3-55 ~]#cmp --help
用法: cmp [选项]... 文件1 [文件2 [跳1 [跳2]]]
逐字节比较两个文件。

<跳1> 和 <跳2> 分别是每个文件要略过的字节数。

长选项的必需参数也是相应短选项的必需参数。
  -b  --print-bytes          打印出内容相异的字节
  -i, --ignore-initial=SKIP         两个输入内容都略过前 SKIP 字节
  -i, --ignore-initial=跳1:跳2      略过 <文件1> 的前 <跳1> 个字节和文件 <文件2>
                                    的前 <跳2> 个字节。
  -l, --verbose              输出所有相异字节的字节数和内容
  -n, --bytes=限制           最多比较 <限制> 个字节
  -s, --quiet, --silent      suppress all normal output
      --help                 显示此帮助信息并退出
  -v, --version              输出版本信息并退出

<跳> 值可以加上以下的单位:
kB=1,000、K=1,024、MB=1,000,000、M=1,048,576、GB=1,000,000,000、G=107,374,182,
还有 T、P、E、Z、Y,如此类推。

如果文件是 “-” 或没给出,则从标准输入读入内容。
如果输入相同,则退出状态为 0;1 表示输入不同;2 表示有错误产生。

ls和dir功能相同,但本质有何区别呢?

[21:15:24 root@C8-3-55 ~]#ll `which dir`
-rwxr-xr-x. 1 root root 166448 5月  11 2019 /usr/bin/dir
[21:16:22 root@C8-3-55 ~]#ll /bin/ls
-rwxr-xr-x. 1 root root 166448 5月  11 2019 /bin/ls
[21:16:29 root@C8-3-55 ~]#cmp /usr/bin/dir /bin/ls  ## 比较两个程序的二进制文件的区别
/usr/bin/dir /bin/ls 不同:第 737 字节,第 2 行 ## 比较结果提示只有一小丢丢区别
[21:18:21 root@C8-3-55 ~]#hexdump -s 730 -Cn 10 /usr/bin/dir ## 通过hexdump 查看dir二进制文件从730开始往后10行
000002da  00 00 47 4e 55 00 b0 4b  be 05                    |..GNU..K..|
000002e4
[21:19:08 root@C8-3-55 ~]#hexdump -s 730 -Cn 10 /bin/ls## 通过hexdump 查看ls二进制文件从730开始往后10行
000002da  00 00 47 4e 55 00 93 77  08 96                    |..GNU..w..|
000002e4
* * * 胖并快乐着的死肥宅 * * *
原文地址:https://www.cnblogs.com/bpzblog/p/14498275.html