diff
# diff 以逐行的方式,比较文本文件的异同处,特别是比较两个版本不同的文件,如果指定要比较目录,则比较目录中相同文件名的文件,但不会比较其中子目录
# diff 的输出描述两个文件的不同,告诉用户怎样改变第一个文件之后与第二个文件保持一致(它是以"行"为单位进行比较的)
#
# -r 对比目录
# -u 以合并格式创建补丁文件,它比默认的格式更紧凑
# -N 确保补丁文件将正确地处理已经创建或删除文件的情况
# -c 显示文件所有内容并标识不同
# -b 不检查空格字符的不同
# ------------------------------------------------------------------------------------------ Example
cat file1.txt
# I need to buy apples.
# I need to run the laundry.
# I need to wash the dog.
# I need to get the car detailed.
cat file2.txt
# I need to buy apples.
# I need to do the laundry.
# I need to wash the car.
# I need to get the dog detailed.
diff file1.txt file2.txt # diff [选项] 改动前的文件(夹) 改动后的文件(夹)
# 2,4c2,4
# 左边的数字 2,4 表示第一个文件中的行
# 中间字母 c 表示需在第一个文件中做的操作 (a=add,c=change,d=delete)
# 右边的数字 2,4 表示第二个文件中的行
# 2,4c2,4 含义: 第一个文件中的第 [2,4] 行(是闭合区间,包括第2和第4行)需做出修改才能与第二个文件中的 [2,4] 行保持一致
# 接下来的内容则告诉用户具体需修改的地方:
# < I need to run the laundry. # 前面带 < 的部分表示左边文件的第[2,4]行的内容
# < I need to wash the dog. #
# < I need to get the car detailed. #
# --- # 中间的 --- 是两个文件内容的分隔符号
# > I need to do the laundry. # 后面带 > 的部分表示右边文件的第[2,4]行的内容
# > I need to wash the car.
# > I need to get the dog detailed.
diff -u file1.txt file2.txt
# --- file1.txt 2021-03-30 17:01:52.599398000 +0800
# +++ file2.txt 2021-03-30 17:02:08.889398000 +0800
# @@ -1,4 +1,4 @@
# I need to buy apples.
# -I need to run the laundry.
# -I need to wash the dog.
# -I need to get the car detailed.
# +I need to do the laundry.
# +I need to wash the car.
# +I need to get the dog detailed.
# ----------------- 说明
2a3 # 第一个文件第 2 行添加下面的内容之后与第二个文件的第3行相同
> aa # 该内容仅存在与第二个文件中,> 表示第二个文件
5a7 # 第一个文件第 5 行添加下面的内容之后与第二个文件的第7行相同
> bb # 该内容仅存在与第二个文件中,> 表示第二个文件
3d2 # 删除第一个文件第 3 行则与第二个文件的第 2 行相等
< aa # 第一个文件待删除的内容是 aa ,< 表示第一个文件
7d5 # 第一个文件第 7 行删除之后与第二个文件第 5 行相等
< bb # 第一个文件待删除的内容是 bb,< 表示第一个文件
# ------------------------------------------------------------------------------------------
# Usage: diff [OPTION]... FILES
# Compare FILES line by line.
#
# Mandatory arguments to long options are mandatory for short options too.
# --normal output a normal diff (the default)
# -q, --brief report only when files differ
# -s, --report-identical-files report when two files are the same
# -c, -C NUM, --context[=NUM] output NUM (default 3) lines of copied context
# -u, -U NUM, --unified[=NUM] output NUM (default 3) lines of unified context
# -e, --ed output an ed script
# -n, --rcs output an RCS format diff
# -y, --side-by-side output in two columns
# -W, --width=NUM output at most NUM (default 130) print columns
# --left-column output only the left column of common lines
# --suppress-common-lines do not output 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
# (can be repeated)
#
# -t, --expand-tabs expand tabs to spaces in output
# -T, --initial-tab make tabs line up by prepending a tab
# --tabsize=NUM tab stops every NUM (default 8) print columns
# --suppress-blank-empty suppress space or tab before empty output lines
# -l, --paginate pass output through 'pr' to paginate it
#
# -r, --recursive recursively compare any subdirectories found
# --no-dereference don't follow symbolic links
# -N, --new-file treat absent files as empty
# --unidirectional-new-file treat absent first files as empty
# --ignore-file-name-case ignore case when comparing file names
# --no-ignore-file-name-case consider case when comparing file names
# -x, --exclude=PAT exclude files that match PAT
# -X, --exclude-from=FILE exclude files that match any pattern in FILE
# -S, --starting-file=FILE start with FILE when comparing directories
# --from-file=FILE1 compare FILE1 to all operands;
# FILE1 can be a directory
# --to-file=FILE2 compare all operands to FILE2;
# FILE2 can be a directory
#
# -i, --ignore-case ignore case differences in file contents
# -E, --ignore-tab-expansion ignore changes due to tab expansion
# -Z, --ignore-trailing-space ignore white space at line end
# -b, --ignore-space-change ignore changes in the amount of white space
# -w, --ignore-all-space ignore all white space
# -B, --ignore-blank-lines ignore changes where lines are all blank
# -I, --ignore-matching-lines=RE ignore changes where all lines match RE
#
# -a, --text treat all files as text
# --strip-trailing-cr strip trailing carriage return on input
#
# -D, --ifdef=NAME output merged file with '#ifdef NAME' diffs
# --GTYPE-group-format=GFMT format GTYPE input groups with GFMT
# --line-format=LFMT format all input lines with LFMT
# --LTYPE-line-format=LFMT format LTYPE input lines with LFMT
# These format options provide fine-grained control over the output
# of diff, generalizing -D/--ifdef.
# LTYPE is 'old', 'new', or 'unchanged'. GTYPE is LTYPE or 'changed'.
# GFMT (only) may contain:
# %< lines from FILE1
# %> lines from FILE2
# %= lines common to FILE1 and FILE2
# %[-][WIDTH][.[PREC]]{doxX}LETTER printf-style spec for LETTER
# LETTERs are as follows for new group, lower case for old group:
# F first line number
# L last line number
# N number of lines = L-F+1
# E F-1
# M L+1
# %(A=B?T:E) if A equals B then T else E
# LFMT (only) may contain:
# %L contents of line
# %l contents of line, excluding any trailing newline
# %[-][WIDTH][.[PREC]]{doxX}n printf-style spec for input line number
# Both GFMT and LFMT may contain:
# %% %
# %c'C' the single character C
# %c'\OOO' the character with octal code OOO
# C the character C (other characters represent themselves)
#
# -d, --minimal try hard to find a smaller set of changes
# --horizon-lines=NUM keep NUM lines of the common prefix and suffix
# --speed-large-files assume large files and many scattered small changes
#
# --help display this help and exit
# -v, --version output version information and exit
#
# FILES are 'FILE1 FILE2' or 'DIR1 DIR2' or 'DIR FILE...' or 'FILE... DIR'.
# If --from-file or --to-file is given, there are no restrictions on FILE(s).
# If a FILE is '-', read standard input.
# Exit status is 0 if inputs are the same, 1 if different, 2 if trouble.
#
# Report bugs to: [email protected]
# GNU diffutils home page: <http://www.gnu.org/software/diffutils/>
# General help using GNU software: <http://www.gnu.org/gethelp/>
patch
# 在数学上来说,diff 是对两个集合的差运算,patch 是对两个集合的和运算
# diff 比较两个文件或文件集合的差异,并记录下来,生成一个 diff 文件,这也是我们常说的 patch 文件,即补丁文件
# patch 能将 diff 文件运用于原来的两个集合之一,从而得到另一个集合
# 简单说 patch 就是利用 diff 制作的补丁来实现的,它将 diff 记录的结果(即补丁)应用到相应文件(夹)上
# -b 备份原文件
# -N 忽略修补的数据较原始文件的版本更旧,或该版本的修补数据已使用过
# -u 把修补数据解译成一致化的差异
# -p0 从补丁文件中剥离的目录级别
# -pN 从补丁文件中剥离的目录级别(N表示拿掉几个斜线)
# ------------------------------------------------------------------------------------------ Example
--- old/modules/pcitable Mon Sep 27 11:03:56 1999
+++ new/modules/pcitable Tue Dec 19 20:05:41 2000
# 参数 -p0 表示从当前目录找一个叫做old的文件夹,在其下找modules下的pcitable文件来执行patch操作
# 参数 -p1 表示忽略第一层目录(不管old),从当前目录寻找modules的文件夹,在其下找pcitable,这样的前提是当前目录必须为modules所在的目录
# 而 diff 补丁文件则可以在任意位置,只要指明了 diff 补丁文件的路径就可以了,当然,可以用相对路径,也可以用绝对路径
cat file1.txt
# I need to buy apples.
# I need to run the laundry.
# I need to wash the dog.
# I need to get the car detailed.
cat file2.txt
# I need to buy apples.
# I need to do the laundry.
# I need to wash the car.
# I need to get the dog detailed.
# 生成补丁文件
diff -u file1.txt file2.txt > /tmp/patch.file
# 修改,更新原始文件 ...
# 在需要被打补丁的目录下执行下列命令打入补丁文件
# -p0 在当前路径下打当前路径的补丁(当前路径的补丁就是当时在制作补丁的时候在该路径下做的)
patch -p0 < patch.file
# ------------------------------------------------------------------------------------------
cat > original/file1.txt <<EOF
This is the original content of file1
EOF
cat > original/file2.txt <<EOF
This is the original content of file2
EOF
cat > modified/file1.txt <<EOF
This is the modified content of file1
EOF
cat > modified/file2.txt <<EOF
This is the modified content of file2
EOF
# 生成差异文件
diff -ruN original modified > mypatch.diff
# 差异内容如下:
# diff -ruN original/file1.txt modified/file1.txt
# --- original/file1.txt 2023-07-13 14:46:48.791834000 +0800
# +++ modified/file1.txt 2023-07-13 14:46:48.916834000 +0800
# @@ -1 +1 @@
# -This is the original content of file1
# +This is the modified content of file1
# diff -ruN original/file2.txt modified/file2.txt
# --- original/file2.txt 2023-07-13 14:46:48.852834000 +0800
# +++ modified/file2.txt 2023-07-13 14:46:48.978834000 +0800
# @@ -1 +1 @@
# -This is the original content of file2
# +This is the modified content of file2
tree
# .
# ├── modified
# │ ├── file1.txt
# │ └── file2.txt
# ├── mypatch.diff
# └── original
# ├── file1.txt
# └── file2.txt
# 将差异文件应用到 original 文件夹(剥离一个目录级别,确保补丁正确应用到目标文件夹中的对应文件上)
cd original
patch -p1 < ../mypatch.diff
cat file1.txt
# This is the modified content of file1
cat file2.txt
# This is the modified content of file2
# ------------------------------------------------------------------------------------------
# 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'.
# -x NUM --debug=NUM Set internal debugging flags.
#
# -v --version Output version info.
# --help Output this help.
Example
cat orgin.txt
# a1
# a2
# a3
cat new.txt
# a1
# x2
# a3
# a4
diff orgin.txt new.txt
# 2c2
# < a2
# ---
# > x2
# 3a4
# > a4
diff -u orgin.txt new.txt
# --- orgin.txt 2023-07-13 09:01:50.473632000 +0800
# +++ new.txt 2023-07-13 09:02:13.156632000 +0800
# @@ -1,3 +1,4 @@
# a1
# -a2
# +x2
# a3
# +a4
diff orgin.txt new.txt > txt.patch
patch -p0 orgin.txt txt.patch
cat orgin.txt
# a1
# x2
# a3
# a4
标签:文件,示例,--,patch,need,diff,txt
From: https://www.cnblogs.com/MoonGlow/p/17553081.html