Linux命令详解1--文件和目录管理之文件查找和比较
1. 文件查找
1.1 strings命令
------- 在对象文件或二进制文件中查找可打印的字符串。字符串是4个或更多可打印的任意序列,以换行或空字符结束。 strings命令对识别随机对象文件很有用。
【语法】:
strings [-a|-|--all] [-f|--print-file-name] [-o] [--help] [-v|--version] [-T bfdname | --target=bfdname]
[-n min-len|-min-len|--bytes=min-len] [-t {o,x,d}[--target=bfdname] |--radix={o,x,d}] file
【选项】:
-a|--all:扫描整个文件而不是只扫描目标文件初始化和装载段
-f|--print-file-name : 在显示字符串前先显示文件名
-t {o,x,d}[--target=bfdname] |--radix={o,x,d}: 输出字符的位置,基于八进制,十进制,十六进制
-o:类似--radix=o;
- :设置显示的最少的字符数,默认是4个字符
-n min-len|-min-len|--bytes=min-len: 找到并输出所有NUL终止符序列
--help: 输出strings命令的选项
-v|--version:strings命令的版本号
-T bfdname | --target=bfdname:指定二进制文件格式
【实例】
查找ls中包含libc的字符串,不区分大小写
sunny@sunny-ThinkPad-T450:~$ strings /bin/ls | grep -i libc libc.so.6 __libc_start_main GLIBC_2.14 GLIBC_2.4 GLIBC_2.17 GLIBC_2.3.4 GLIBC_2.2.5 GLIBC_2.3
在上面的基础上查看-f选项的效果: sunny@sunny-ThinkPad-T450:~$ strings -f /bin/ls | grep -i libc /bin/ls: libc.so.6 /bin/ls: __libc_start_main /bin/ls: GLIBC_2.14 /bin/ls: GLIBC_2.4 /bin/ls: GLIBC_2.17 /bin/ls: GLIBC_2.3.4 /bin/ls: GLIBC_2.2.5 /bin/ls: GLIBC_2.3
1.2 which命令
--------用于查找并显示给定命令的绝对路径,环境变量PATH中保存了查找命令时需要遍历的目录。
【语法】
which [-a] filename
【选项】
-a :打印匹配到的命令的路径
【实例】
sunny@sunny-ThinkPad-T450:~$ which ls /bin/ls sunny@sunny-ThinkPad-T450:~$ which ll sunny@sunny-ThinkPad-T450:~$ which which /usr/bin/which sunny@sunny-ThinkPad-T450:~$ which wc /usr/bin/wc sunny@sunny-ThinkPad-T450:~$ which -a find /usr/bin/find
1.3 whereis命令
-------用来定位一个二进制文件或源文件或者某个命令的man手册页文件等
【语法】
whereis [-bmsu] [-BMS directory... -f] filename...
【选项】
-b:仅搜索二进制文件 -m:仅搜索man手册文件 -s:仅搜索源文件 -u:查找不包含指定类型的文件 -B<后跟目录>:只在该目录下查找二进制文件 -M<后跟目录>:只在该目录下查找说明文件 -S<后跟目录>:只在该目录下查找源代码文件
【实例】
sunny@sunny-ThinkPad-T450:~$ whereis git git: /usr/bin/git /usr/bin/X11/git /usr/share/man/man1/git.1.gz sunny@sunny-ThinkPad-T450:~$ whereis -b git git: /usr/bin/git /usr/bin/X11/git sunny@sunny-ThinkPad-T450:~$ whereis -m ls ls: /usr/share/man/man1/ls.1.gz sunny@sunny-ThinkPad-T450:~$ whereis -m git git: /usr/share/man/man1/git.1.gz sunny@sunny-ThinkPad-T450:~$ whereis -s ls ls:
1.4 locate命令
----用来查找文件或目录
locate命令其实是find -name的另一种写法,但是要比后者快得多,原因在于它不搜索具体目录,而是搜索一个数据库/var/lib/locatedb,这个数据库中含有本地所有文件信息。Linux系统自动创建这个数据库,并且每天自动更新一次,所以使用locate命令查不到最新变动过的文件。为了避免这种情况,可以在使用locate之前,先使用updatedb命令,手动更新数据库。
来自: http://man.linuxde.net/locate_slocate
【语法】
locate [-ir...] keyword
【选项】
-i:忽略大小写的差异
-r:后面可接正则表达式的显示方式
-A|--all:打印所有与keyword匹配的文件
-c:输出查找到的与keyword匹配的文件的总数
keyword:文件的部分名称即可,即要查找的文件名中含有的字符串
【实例】
#打印/etc目录中以sh开头的文件 $ locate /etc/sh /etc/shadow /etc/shadow~ /etc/shells $ locate -c passwd 473 $ locate passwd /etc/passwd /etc/passwd~ .....下面省略.....
1.5 find命令
-----find命令用来在指定目录下查找文件。任何位于参数之前的字符串都将被视为欲查找的目录名。如果使用该命令时,不设置任何参数,则find命令将在当前目录下查找子目录与文件。并且将查找到的子目录和文件全部进行显示。
【语法】
find [PATH] [option] [action]
【选项】
1.与时间有关的参数:n(如,n之前1天内被修改),+n(如,n之前被修改),-n(如,n之内被修改)
-amin<分钟>:查找在指定时间曾被存取过的文件或目录,单位以分钟计算; -anewer<参考文件或目录>:查找其存取时间较指定文件或目录的存取时间更接近现在的文件或目录; -atime<24小时数>:查找在指定时间曾被存取过的文件或目录,单位以24小时计算; -cmin<分钟>:查找在指定时间之时被更改过的文件或目录; -cnewer<参考文件或目录>查找其更改时间较指定文件或目录的更改时间更接近现在的文件或目录; -ctime<24小时数>:查找在指定时间之时被更改的文件或目录,单位以24小时计算;
-mmin:修改
-mtime:
-newer:文件新旧 -daystart:从本日开始计算时间; -depth:从指定目录下最深层的子目录开始查找; -expty:寻找文件大小为0 Byte的文件,或目录下没有任何子目录或文件的空目录; -exec<执行指令>:假设find指令的回传值为True,就执行该指令; -false:将find指令的回传值皆设为False; -fls<列表文件>:此参数的效果和指定“-ls”参数类似,但会把结果保存为指定的列表文件; -follow:排除符号连接; -fprint<列表文件>:此参数的效果和指定“-print”参数类似,但会把结果保存成指定的列表文件; -fprint0<列表文件>:此参数的效果和指定“-print0”参数类似,但会把结果保存成指定的列表文件; -fprintf<列表文件><输出格式>:此参数的效果和指定“-printf”参数类似,但会把结果保存成指定的列表文件; -fstype<文件系统类型>:只寻找该文件系统类型下的文件或目录; -gid<群组识别码>:查找符合指定之群组识别码的文件或目录; -group<群组名称>:查找符合指定之群组名称的文件或目录; -help或——help:在线帮助; -ilname<范本样式>:此参数的效果和指定“-lname”参数类似,但忽略字符大小写的差别; -iname<范本样式>:此参数的效果和指定“-name”参数类似,但忽略字符大小写的差别; -inum:查找符合指定的inode编号的文件或目录; -ipath<范本样式>:此参数的效果和指定“-path”参数类似,但忽略字符大小写的差别; -iregex<范本样式>:此参数的效果和指定“-regexe”参数类似,但忽略字符大小写的差别; -links<连接数目>:查找符合指定的硬连接数目的文件或目录; -iname<范本样式>:指定字符串作为寻找符号连接的范本样式; -ls:假设find指令的回传值为Ture,就将文件或目录名称列出到标准输出; -maxdepth<目录层级>:设置最大目录层级; -mindepth<目录层级>:设置最小目录层级; -mmin<分钟>:查找在指定时间曾被更改过的文件或目录,单位以分钟计算; -mount:此参数的效果和指定“-xdev”相同; -mtime<24小时数>:查找在指定时间曾被更改过的文件或目录,单位以24小时计算;
-name<范本样式>:指定字符串作为寻找文件或目录的范本样式; -newer<参考文件或目录>:查找其更改时间较指定文件或目录的更改时间更接近现在的文件或目录; -nogroup:找出不属于本地主机群组识别码的文件或目录; -noleaf:不去考虑目录至少需拥有两个硬连接存在; -nouser:找出不属于本地主机用户识别码的文件或目录; -ok<执行指令>:此参数的效果和指定“-exec”类似,但在执行指令之前会先询问用户,若回答“y”或“Y”,则放弃执行命令; -path<范本样式>:指定字符串作为寻找目录的范本样式; -perm<权限数值>:查找符合指定的权限数值的文件或目录; -print:假设find指令的回传值为Ture,就将文件或目录名称列出到标准输出。格式为每列一个名称,每个名称前皆有“./”字符串; -print0:假设find指令的回传值为Ture,就将文件或目录名称列出到标准输出。格式为全部的名称皆在同一行; -printf<输出格式>:假设find指令的回传值为Ture,就将文件或目录名称列出到标准输出。格式可以自行指定; -prune:不寻找字符串作为寻找文件或目录的范本样式; -regex<范本样式>:指定字符串作为寻找文件或目录的范本样式; -size<文件大小>:查找符合指定的文件大小的文件; -true:将find指令的回传值皆设为True; -typ<文件类型>:只寻找符合指定的文件类型的文件; -uid<用户识别码>:查找符合指定的用户识别码的文件或目录; -used<日数>:查找文件或目录被更改之后在指定时间曾被存取过的文件或目录,单位以日计算; -user<拥有者名称>:查找符和指定的拥有者名称的文件或目录; -version或——version:显示版本信息; -xdev:将范围局限在先行的文件系统中; -xtype<文件类型>:此参数的效果和指定“-type”参数类似,差别在于它针对符号连接检查。
【实例】
根据文件或者正则表达式进行匹配 列出当前目录及子目录下所有文件和文件夹 $ find . 在/home目录下查找以.txt结尾的文件名 $ find /home -name "*.txt" 同上,但忽略大小写 $ find /home -iname "*.txt" 当前目录及子目录下查找所有以.txt和.pdf结尾的文件 $ find . \( -name "*.txt" -o -name "*.pdf" \) 或 find . -name "*.txt" -o -name "*.pdf" 匹配文件路径或者文件 $ find /usr/ -path "*local*" 基于正则表达式匹配文件路径 $ find . -regex ".*\(\.txt\|\.pdf\)$" 同上,但忽略大小写 $ find . -iregex ".*\(\.txt\|\.pdf\)$" 否定参数 找出/home下不是以.txt结尾的文件 $ find /home ! -name "*.txt" 根据文件类型进行搜索 $ find . -type 类型参数 类型参数列表: f 普通文件 l 符号连接 d 目录 c 字符设备 b 块设备 s 套接字 p Fifo 基于目录深度搜索 向下最大深度限制为3 $ find . -maxdepth 3 -type f 搜索出深度距离当前目录至少2个子目录的所有文件 $ find . -mindepth 2 -type f 根据文件时间戳进行搜索 $ find . -type f 时间戳 UNIX/Linux文件系统每个文件都有三种时间戳: 访问时间(-atime/天,-amin/分钟):用户最近一次访问时间。 修改时间(-mtime/天,-mmin/分钟):文件最后一次修改时间。 变化时间(-ctime/天,-cmin/分钟):文件数据元(例如权限等)最后一次修改时间。 搜索最近七天内被访问过的所有文件 $ find . -type f -atime -7 搜索恰好在七天前被访问过的所有文件 $ find . -type f -atime 7 搜索超过七天内被访问过的所有文件 $ find . -type f -atime +7 搜索访问时间超过10分钟的所有文件 $ find . -type f -amin +10 找出比file.log修改时间更长的所有文件 $ find . -type f -newer file.log 根据文件大小进行匹配 $ find . -type f -size 文件大小单元 文件大小单元: b —— 块(512字节) c —— 字节 w —— 字(2字节) k —— 千字节 M —— 兆字节 G —— 吉字节 搜索大于10KB的文件 $ find . -type f -size +10k 搜索小于10KB的文件 $ find . -type f -size -10k 搜索等于10KB的文件 $ find . -type f -size 10k 删除匹配文件 删除当前目录下所有.txt文件 $ find . -type f -name "*.txt" -delete 根据文件权限/所有权进行匹配 当前目录下搜索出权限为777的文件 $ find . -type f -perm 777 找出当前目录下权限不是644的php文件 $ find . -type f -name "*.php" ! -perm 644 找出当前目录用户tom拥有的所有文件 $ find . -type f -user tom 找出当前目录用户组sunk拥有的所有文件 $ find . -type f -group sunk 借助-exec选项与其他命令结合使用 找出当前目录下所有root的文件,并把所有权更改为用户tom $ find .-type f -user root -exec chown tom {} \; 上例中,{} 用于与-exec选项结合使用来匹配所有文件,然后会被替换为相应的文件名。 找出自己家目录下所有的.txt文件并删除 $ find $HOME/. -name "*.txt" -ok rm {} \; 上例中,-ok和-exec行为一样,不过它会给出提示,是否执行相应的操作。 查找当前目录下所有.txt文件并把他们拼接起来写入到all.txt文件中 $ find . -type f -name "*.txt" -exec cat {} \; > all.txt 将30天前的.log文件移动到old目录中 $ find . -type f -mtime +30 -name "*.log" -exec cp {} old \; 找出当前目录下所有.txt文件并以“File:文件名”的形式打印出来 $ find . -type f -name "*.txt" -exec printf "File: %s\n" {} \; 因为单行命令中-exec参数中无法使用多个命令,以下方法可以实现在-exec之后接受多条命令 -exec ./text.sh {} \; 搜索但跳出指定的目录 查找当前目录或者子目录下所有.txt文件,但是跳过子目录sk $ find . -path "./sk" -prune -o -name "*.txt" -print find其他技巧收集 要列出所有长度为零的文件 find . -empty
sunny@sunny-ThinkPad-T450:~/test/file$ find . -name "*.txt" ./test1.txt ./test2.txt ./test3.txt
来自: http://man.linuxde.net/find
2.文件比较
2.1 cmp命令
----cmp - compare two files byte by byte,比较两个文件的差异。
【语法】
cmp [option] ... file1 [file2 [SKIP1 [SKIP2]]]
【选项】
-b, --print-bytes,打印有差别的字节 -i, --ignore-initial=SKIP,两文件跳过相同的字节数再比较 -i, --ignore-initial=SKIP1:SKIP2,文件1跳过SKIP1后与文件2跳过SKIP2后再比较 -l, --verbose,输出字节总数及不同的字节值 -n, --bytes=LIMIT,比较的字节数的限制,最多比较LIMIT字节 -s, --quiet, --silent,强制不输出,即使有差异也不输出信息 --help display this help and exit,帮助文档 -v, --version,输出版本信息
【实例】
#比较两个文件,指出两文件的第一个不同点 sunny@sunny-ThinkPad-T450:~/test/file$ cmp test1.txt test2.txt test1.txt test2.txt 不同:第 2 字节,第 1 行 sunny@sunny-ThinkPad-T450:~/test/file$ cat test1.txt test TEST sunny@sunny-ThinkPad-T450:~/test/file$ cat test2.txt tast TASTESTR #使用-b选项,比较两文件的不同之处,再输出两文件中出现不同的值 sunny@sunny-ThinkPad-T450:~/test/file$ cmp -b test1.txt test2.txt test1.txt test2.txt 不同:第 1 行,第 2 字节为 145 e 141 a
#比较两个文件中,都跳过2个字节后的差异
sunny@sunny-ThinkPad-T450:~/test/file$ cmp -i 2 test1.txt test2.txt 2
test1.txt test2.txt 不同:第 5 字节,第 2 行
sunny@sunny-ThinkPad-T450:~/test/file$ cat test1.txt
test
TEST
sunny@sunny-ThinkPad-T450:~/test/file$ cat test2.txt
tast
TASTESTR
sunny@sunny-ThinkPad-T450:~/test/file$ cmp -i 1:2 test1.txt test2.txt
test1.txt test2.txt 不同:第 1 字节,第 1 行
sunny@sunny-ThinkPad-T450:~/test/file$ cmp -b -i 1:2 test1.txt test2.txt
test1.txt test2.txt 不同:第 1 行,第 1 字节为 145 e 163 s
#比较两个文件的字节差异,显示出在第几个字节不同,且不同的两个字节的字节值
sunny@sunny-ThinkPad-T450:~/test/file$ cmp -l test1.txt test2.txt
2 145 141
7 105 101
10 12 105
11 12 123
cmp:test1.txt 已结束
#使用-n比较两个文件中的字节数,对其做限制。比较1个字节,因为两字节相同则没有输出,当最多比较两个字节时,输出差异
sunny@sunny-ThinkPad-T450:~/test/file$ cmp -n 1 test1.txt test2.txt
sunny@sunny-ThinkPad-T450:~/test/file$ cmp -n 2 test1.txt test2.txt
test1.txt test2.txt 不同:第 2 字节,第 1 行
##-s的使用,强制不输出差异化信息
sunny@sunny-ThinkPad-T450:~/test/file$ cmp -s test1.txt test2.txt
sunny@sunny-ThinkPad-T450:~/test/file$
2.2 diff命令
--diff - compare files line by line,比较两文件行与行之间的差异,即逐行比较两个文件的差异
【语法】
diff [OPTION]... FILES
【选项】
--normal,默认输出,output a normal diff (the default) -q, --brief,仅显示有无差异,不显示其他信息; -s, --report-identical-files,当两个文件一样时,显示信息 -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 -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 whose lines are all blank -I, --ignore-matching-lines=RE ignore changes whose lines all 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
【实例】
##默认比较两文件的差异 字母"a"、"d"、"c"分别表示添加、删除及修改操作。
sunny@sunny-ThinkPad-T450:~/test/file$ diff test1.txt test2.txt 1,3c1,2 < test < TEST ##<来自文件1的输出 < --- > tast > TASTESTR ##>来自文件2
#只显示文件不同,不显示其他信息 -q
sunny@sunny-ThinkPad-T450:~/test/file$ diff -q test1.txt test2.txt
文件 test1.txt 和 test2.txt 不同
sunny@sunny-ThinkPad-T450:~/test/file$ diff -q test2.txt test3.txt
sunny@sunny-ThinkPad-T450:~/test/file$ cat test2.txt
tast
TASTESTR
sunny@sunny-ThinkPad-T450:~/test/file$ cat test3.txt
tast
TASTESTR
##文件相同时 -s
sunny@sunny-ThinkPad-T450:~/test/file$ diff -s test2.txt test3.txt
檔案 test2.txt 和 test3.txt 相同
2.3 diff3命令
----diff3 - compare three files line by line,逐行比较3个文件
【语法】
diff3 [OPTION]... MYFILE OLDFILE YOURFILE
【选项】
-a:把所有的文件都当做文本文件按照行为单位进行比较,即给定的文件不是文本文件; -A:合并第2个文件和第3个文件之间的不同到第1个文件中,有冲突内容用括号括起来; -B:与选项“-A”功能相同,但是不显示冲突的内容; -e/--ed:生成一个“-ed”脚本,用于将第2个文件和第3个文件之间的不同合并到第1个文件中; --easy-only:除了不显示互相重叠的变化,与选项“-e”的功能相同; -i:为了和system V系统兼容,在“ed”脚本的最后生成“w”和“q”命令。此选项必须和选项“-AeExX3”连用,但是不能和“-m”连用; --initial-tab:在正常格式的行的文本前,输出一个TAB字符而非两个空白字符。此选项将导致在行中TAB字符的对齐方式看上去规范。
【实例】
sunny@sunny-ThinkPad-T450:~/test/file$ diff3 test2.txt test1.txt test3.txt ====2 1:1,2c 3:1,2c tast TASTESTR 2:1,3c test TEST sunny@sunny-ThinkPad-T450:~/test/file$ cat test2.txt tast TASTESTR sunny@sunny-ThinkPad-T450:~/test/file$ diff3 -A test2.txt test1.txt test3.txt 2a >>>>>>> test3.txt . 0a <<<<<<< test1.txt test TEST