本文共 15199 字,大约阅读时间需要 50 分钟。
Linux的四剑客
作者:张首富2018/07/15[TOC]find
查找文件或目录find - search for files in a directory hierarchy 搜索目录层次结构中的文件
用来在指定目录下面查找文件或目录,任何位于参数之前的字符串都被视为想在那个目录下面查找`find 目录 选项 参数`
d
目录
f
文件l
链接文件实例: [root@zsf tmp]# touch 1.txt 2.txt[root@zsf tmp]# mkdir a b [root@zsf tmp]# find /tmp/ -type f /tmp/1.txt/tmp/2.txt[root@zsf tmp]# find /tmp/ -type d/tmp//tmp/.ICE-unix/tmp/b/tmp/a
-name
按照文件名字查找支持正则匹配,但是要加""
[root@zsf tmp]# find /tmp/ -name *.txt #报错find: paths must precede expression: 2.txtUsage: find [-H] [-L] [-P] [-Olevel] [-D help|tree|search|stat|rates|opt|exec] [path...] [expression][root@zsf tmp]# find /tmp/ -name "*.txt"/tmp/1.txt/tmp/2.txt
-maxdepth
查找目录的级数查找几层目录,/是第一级目录/tmp/就属于第二级目录
[root@zsf /]# find / -maxdepth 2 -name 1.txt/tmp/1.txt[root@zsf /]# find / -maxdepth 3 -name 1.txt/tmp/test/1.txt/tmp/1.txt
-size
按文件大小查找后面需要跟单位 c
表示字节
k
M
+x
代表大小大于X的-x
代表大小小于X的x
代表大小刚好等于X的 [root@zsf /]# dd if=/dev/zero of\=/tmp/find_test.txt count\=1 bs\=10M 1+0 records in1+0 records out10485760 bytes (10 MB) copied, 0.00732409 s, 1.4 GB/s[root@zsf /]# dd if=/dev/zero of\=/tmp/find_test_max.txt count\=1 bs\=11M 1+0 records in1+0 records out11534336 bytes (12 MB) copied, 0.00994042 s, 1.2 GB/s[root@zsf /]# dd if=/dev/zero of\=/tmp/find_test_min.txt count\=1 bs\=9M 1+0 records in1+0 records out9437184 bytes (9.4 MB) copied, 0.0620404 s, 152 MB/s[root@zsf /]# find /tmp -size +10M/tmp/find_test_max.txt[root@zsf /]# find /tmp -size -10M/tmp/tmp/.ICE-unix/tmp/find_test_min.txt[root@zsf /]# find /tmp -size 10M/tmp/find_test.txt#如果查找大于6M小于9M的文件可以省略其中的-a选项[root@backup tmp]# find /tmp/ -size +6M -a -size -9M/tmp/find_test_2.txt/tmp/find_test_3.txt[root@backup tmp]# find /tmp/ -size +6M -size -9M/tmp/find_test_2.txt/tmp/find_test_3.txt#但如果想取小于6M和大于9M的文件,中间的-o选项就不能省去[root@backup tmp]# find /tmp/ -size -6M -o -size +9M/tmp//tmp/.ICE-unix/tmp/find_test_1.txt
-mtime
(Modify时间)按照修改时间来查找,单位为天数,+ - 默认和上述一样
[root@zsf tmp]# touch -m -d '2018-07-07' find_test.txt [root@zsf tmp]# touch -m -d '2018-07-13' find_test_max.txt [root@zsf tmp]# find /tmp -mtime +2/tmp/find_test.txt[root@zsf tmp]# find /tmp -mtime -2/tmp/tmp/.ICE-unix/tmp/find_test_max.txt/tmp/find_test_min.txt
-atime
(Access时间)按照访问时间来查找
-ctime按照更改时间来查找(Change时间)-perm
按照权限来查找后面必须跟数字权限
[root@zsf tmp]# chmod 777 find_test.txt [root@zsf tmp]# find /tmp -perm 0644/tmp/find_test_max.txt/tmp/find_test_min.txt[root@zsf tmp]# find /tmp -perm 0777/tmp/find_test.txt
-user
按照文件属主来查询[root@zsf tmp]# chown zsf find_test.txt [root@zsf tmp]# find /tmp/ -user zsf /tmp/find_test.txt[root@zsf tmp]# lltotal 30720-rw-r--r-- 1 root zsf 11534336 Jul 13 2018 find_test_max.txt-rw-r--r-- 1 root root 9437184 Jul 10 19:45 find_test_min.txt-rwxrwxrwx 1 zsf root 10485760 Jul 7 00:00 find_test.txt
-nouser
查找无效属主的文件,属主不存在/etc/passwd
里面的,系统里面不允许有这类文件[root@zsf tmp]# userdel zsf[root@zsf tmp]# find /tmp/ -nouser /tmp/find_test.txt
-group
按照文件属组来查询[root@zsf tmp]# chown :zsf find_test_max.txt [root@zsf tmp]# find /tmp/ -group zsf /tmp/find_test_max.txt[root@zsf tmp]# lltotal 30720-rw-r--r-- 1 root zsf 11534336 Jul 13 2018 find_test_max.txt-rw-r--r-- 1 root root 9437184 Jul 10 19:45 find_test_min.txt-rwxrwxrwx 1 zsf root 10485760 Jul 7 00:00 find_test.txt
-nogroup
查找无效属组的文件,系统中不允许存在-delete
查到之后删除(比较危险)!
取反环境和2.1.3.15相同
不属于zsf这个用户的或者权限是777的[root@zsf tmp]# find /tmp/ ! -user zsf -o -perm 777/tmp//tmp/1.sh/tmp/3.sh/tmp/4.sh
-a
and 取交集[root@zsf tmp]# chown zsf 1.sh [root@zsf tmp]# chown zsf 2.sh [root@zsf tmp]# chmod 777 1.sh [root@zsf tmp]# ll total 0-rwxrwxrwx 1 zsf root 0 Jul 10 20:42 1.sh-rw-r--r-- 1 zsf root 0 Jul 10 20:39 2.sh-rw-r--r-- 1 root root 0 Jul 10 20:39 3.sh-rw-r--r-- 1 root root 0 Jul 10 20:42 4.sh找属于zsf并且权限是777的文件[root@zsf tmp]# find /tmp/ -user zsf -a -perm 777/tmp/1.sh
-o
or 取并集环境和2.1.3.15相同
[root@zsf tmp]# find /tmp/ -user zsf -o -perm 777/tmp/2.sh/tmp/1.sh
-exec
理解为传参find命令对匹配的文件执行该参数所给出的shell命令。相应命令的形式为'command' { } \;
,注意{ }
和\;
之间的空格。
[root@oldboy_50 tmp]# touch 123[root@oldboy_50 tmp]# ll total 0-rw-r--r-- 1 root root 0 Jul 25 00:16 123[root@oldboy_50 tmp]# find /tmp -name 123 -type f -exec mv {} 321 \;[root@oldboy_50 tmp]# ls 321
-exec
和加 | xarge
的区别使用exec的时候是边查找边执行
| xarge
是find
管道前处理完事之后,才会传递到后面 |
和 |xarge
的区别|
是把前面的执行结果当做文本来处理
|xargs
是把前面的执行结果当做文件名来处理 grep
和egrep
和fgrep
的作用大致相同,都是查找出匹配的行,然后打印出来。
grep
选项 “要过滤的字符串/正则表达式” 对象
-i
不区分字符串大小写[root@oldboy50 tmp]# grep "qwe" grep_file.txt qweqwe[root@oldboy50 tmp]# grep "QWE" grep_file.txt QWEQWE[root@oldboy50 tmp]# grep -i "QWE" grep_file.txt QWEQWEqweqwe
-v
取反,输出不匹配字符串的行[root@oldboy50 tmp]# grep -i -v "QWE" grep_file.txt asdasdasd
-A num
显示匹配到结果的行,并显示他后面的num行[root@oldboy50 /]# grep -A "^ntp" /etc/passwdgrep: ^ntp: invalid context length argument #报错是因为-A选项之后没有跟参数[root@oldboy50 /]# grep -A 3 "sshd" /etc/passwdsshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologintcpdump:x:72:72::/:/sbin/nologinzsf:x:500:500::/home/zsf:/bin/bashrsync:x:501:501::/home/rsync:/sbin/nologin
-B num
显示匹配到结果的行,并显示他前面的num行[root@oldboy50 tmp]# grep -B 3 "sshd" /etc/passwdntp:x:38:38::/etc/ntp:/sbin/nologinsaslauth:x:499:76:Saslauthd user:/var/empty/saslauth:/sbin/nologinpostfix:x:89:89::/var/spool/postfix:/sbin/nologinsshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
-C num
显示匹配到结果的行,并显示他前、后面的num行[root@oldboy50 tmp]# grep -C 3 "sshd" /etc/passwdntp:x:38:38::/etc/ntp:/sbin/nologinsaslauth:x:499:76:Saslauthd user:/var/empty/saslauth:/sbin/nologinpostfix:x:89:89::/var/spool/postfix:/sbin/nologinsshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologintcpdump:x:72:72::/:/sbin/nologinzsf:x:500:500::/home/zsf:/bin/bashrsync:x:501:501::/home/rsync:/sbin/nologin
-E
相当于egrep
,可以多条件匹配[root@oldboy50 tmp]# grep -E "root|rsync|zsf" /etc/passwdroot:x:0:0:root:/root:/bin/bashoperator:x:11:0:operator:/root:/sbin/nologinzsf:x:500:500::/home/zsf:/bin/bashrsync:x:501:501::/home/rsync:/sbin/nologin[root@oldboy50 tmp]# grep "root|rsync|zsf" /etc/passwd #如果不加-E选项,他就会认为你要查找引号里面整体的字符串,所以没有匹配到的结果[root@oldboy50 tmp]# egrep "root|rsync|zsf" /etc/passwdroot:x:0:0:root:/root:/bin/bashoperator:x:11:0:operator:/root:/sbin/nologinzsf:x:500:500::/home/zsf:/bin/bashrsync:x:501:501::/home/rsync:/sbin/nologin
. `匹配单个字符
[root@oldboy50 tmp]# cat >grep_file.txt <<1> zsdf> zaf> zef> 1[root@oldboy50 tmp]# grep "^z.f$" grep_file.txt zafzef
*
代表任意字符,一般配合.
使用[root@oldboy50 tmp]# grep "^z.*f$" grep_file.txt zsdfzafzef
###\<word
查找以word
字符串开头的单词,所在的行
[root@oldboy_50 tmp]# grep "\
word\>
查找以word
字符串结束的单词,所在的行[root@oldboy_50 tmp]# grep "root\>" 1.txt dasdas 123root dasdasroot
###\<word\>
查找包括word
这个单词的行
[root@oldboy_50 tmp]# grep "\" 1.txt rootdasdas root dasdas
x\{M\}
重复字符x,M
次[root@oldboy50 tmp]# grep "a\{2}" grep_file.txt aasssasasaassssaa
x\{M,\}
重复字符x
,最少M
次x\{M,n\}
重复字符x
,最少M
次,最多n
次[root@oldboy50 tmp]# grep "s\{2,5}" grep_file.txt aasssasasaassssaa
[]
匹配一个指定范围的字符,[root@oldboy50 tmp]# cat >grep_file.txt <123a123> 123b123> 123f123> EOF[root@oldboy50 tmp]# grep "[a,b]" grep_file.txt 123a123123b123
###[^ ]
匹配一个不存在这个范围内的字符
grep的宗旨:显示一切的匹配行,这句话的是理解这个选项的重中之重测试使用的原文件[root@oldboy_50 tmp]# cat test.txt aabbccaaeebbaaffggbbcceeabccaaaaaabbb
####测试1:
[root@oldboy_50 tmp]# grep [^a] test.txt aabbcc 匹配了b和caaeebb 匹配了e和baaffgg 匹配了f和gbbccee 匹配了b和c和eabcc 匹配了b和cbbbbbb 匹配了b我们发现这时候aabbcc,aaeebb都出来了,并没有过滤a这个字符啊,其实已经过滤掉了a,grep的核心是“显示所有匹配的行”。所以几行显示出来并不是应为匹配了aa而是匹配了后面的bbcc,所以这一行才会显示出来。[root@oldboy_50 tmp]# grep [^abc] test.txt aaeebb 匹配了eaaffgg 匹配了fgbbccee 匹配了e
sed - stream editor for filtering and transforming text
sed [OPTION]... {script-only-if-no-other-script} [input-file]...
sed 选项 命令 文件 -e
多点编辑,每个条件前面都必须加-e
选项,不加的那个就不执行在一个sed里面同时执行多种操作
一条sed命令,删除第二行,和在第5行后面增加一串字符[root@backup tmp]# sed -e "2d" -e "5a test" 1.txt 1345test
-n
取消默认输出sed命令默认的是把文件的每一行都输出到屏幕上。匹配到的行输出两次,我们用-n取消默认输出
[root@backup tmp]# seq 5 >1.txt[root@backup tmp]# sed "/1/p" 1.txt 112345[root@backup tmp]# sed -n "/1/p" 1.txt1
-i
直接对文件操作,最后放到最后使用[root@backup tmp]# sed "s#1#a#gp" 1.txt aa2[root@backup tmp]# cat 1.txt12[root@backup tmp]# sed -in "s#1#a#g" 1.txt [root@backup tmp]# cat 1.txta2
[root@oldboy_50 tmp]#sed -i.bak "1d" 1.txt [root@oldboy_50 tmp]#ll -d 1.txt 1.txt.bak -rw-r--r-- 1 root root 0 Dec 12 22:01 1.txt-rw-r--r-- 1 root root 0 Dec 12 05:05 1.txt.bak
-r
支持正则表达式[n1,[n2]] function
(功能)
n1,n2
不一定存在,一般代表(选择进行动作的行数) a
新增,在匹配到的行后面插入a
的后面可以接字符串,这些字符串会在新的一行(目的的下一行)出现
[root@backup tmp]# sed "2,4a asdasd" 1.txt #在第2,3,4行后面增加一行asdasd内容12asdasd3asdasd4asdasd5[root@backup tmp]# sed "/3/a dasda" 1.txt #在匹配到的行后面增加123dasda45
c
取代c
后面可以接字符串,这些字符串会取代目标行的内容
[root@backup tmp]# sed "2,4c asdasd" 1.txt #一行内容取代多行1asdasd5[root@backup tmp]# sed "2,4c asdasd\n31312312\ndd33" 1.txt #多行取代多行,取代行后面要加\n来换行1asdasd31312312dd335[root@backup tmp]# sed "/3/c dasda" 1.txt #取代匹配到的行12dasda45
d
删除d
一般后面不接内容,删除目标
[root@backup tmp]# sed "/3/d" 1.txt #删除匹配到的行1245[root@backup tmp]# sed "2,4d" 1.txt #删除指定位置的行15
p
打印选择将那个数据输出,一般配合-n
(安静)使用
[root@backup tmp]# sed -n "s#2#a#gp" 1.txta
s
替换可以直接进行取代的工作。通常用法s#原内容#替换成内容#g
#
就是一个分隔符,可以用任意字符替换
[root@backup tmp]# sed -n "s#2#a#gp" 1.txt #分隔字符串是什么没影响a[root@backup tmp]# sed -n "s/2/a/gp" 1.txta
i
插入,在匹配到的行前面插入[root@backup tmp]# sed "/3/i dadas" 1.txt12dadas345
N
读取/附加下一行输入到模式空间(一次性读取两行)sed = 参数有显示行号的功能,但是行号和内容不在一行,我们想让他在一行,sed "N"
帮我们解决了这个问题。
[root@oldboy_50 tmp]# sed 'N;s#\n#:#' 3.txt 1 10:2 113 12:4 135 14:6 157 16:8 17
这个里面必须要把\n
给替换掉,如果不替换掉,你会发现他的第二行没有给第一行一块读取啊,可能就会认为linux欺骗了你,实际Linux是不会欺骗你的。没在一行是因为 输出的时候有一个\n
又把第二行给换下去了。
g
全局替换,如果加g
的话他会把所有的内容都变成1行,而不是只替换第一个了 =
显示行号,一般配合 N
使用[root@oldboy_50 tmp]# sed = nginx.txt | sed 'N;s/\n/:/' 1:a2:b3:c4:d5:e6:f7:g
awk是一个强大的文本分析工具,相对于grep的查找,sed的编辑,awk在其对数据的分析并生成报告时,显得尤为强大。简单的来说awk就是把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分在进行各种分析处理。
awk '{pattern + action}' {filenames}
awk [-F field-separator] 'commands' input-file(s)
将所有的awk命令插入一个文件,并使awk程序可执行,然后awk命令解释器作为脚本的首行,一遍通过键入脚本名称来调用。
相当于shell脚本首行的:#!/bin/sh
可以换成:#!/bin/awk
将所有的awk命令插入一个单独的文件,然后调用awk -f awk-script-file input-file(s)
其中,-f
选项加载awk-script-file中的awk脚本,input-file(s)跟上面的是一样的。 -F
指定分隔符,默认是以空格
分隔[root@oldboy_50 tmp]# cat >>awk_test.txt<123:321 456 789:987> EOF[root@oldboy_50 tmp]# awk '{print ' awk_test.txt 123:321[root@oldboy_50 tmp]# awk -F ":" '{print [root@oldboy_50 tmp]# cat >>awk_test.txt< 123:321 456 789:987> EOF[root@oldboy_50 tmp]# awk '{print }' awk_test.txt 123}
$0,$1.........
匹配到的第几块域$0
代表匹配到的所有域,整行
$1
代表匹配到的第一个域,$2
代表匹配到的第二个域 [root@oldboy_50 tmp]# cat awk_test.txt 123:321 456 789:987[root@oldboy_50 tmp]# awk -F ":" '{print ' awk_test.txt 123:321 456 789:987[root@oldboy_50 tmp]# awk -F ":" '{print [root@oldboy_50 tmp]# cat awk_test.txt 123:321 456 789:987[root@oldboy_50 tmp]# awk -F ":" '{print }' awk_test.txt 123[root@oldboy_50 tmp]# awk -F ":" '{print }' awk_test.txt 321 456 789}
BEGIN
头部,后面跟'{print "头部信息"}'
,给输出加上头部
[root@oldboy_50 tmp]# awk -F ":" 'BEGIN {print "user_name\tHome_directory" {print [root@oldboy_50 tmp]# awk -F ":" 'BEGIN {print "user_name\tHome_directory""\t"}' /etc/passwd user_name Home_directoryroot /rootbin /bindaemon /sbinadm /var/admlp /var/spool/lpd}
END
尾部,在输出的最后一行加入内容,后面跟'{print "尾部信息"}'
[root@oldboy_50 tmp]# awk -F ":" 'BEGIN {print "开始" {print [root@oldboy_50 tmp]# awk -F ":" 'BEGIN {print "开始"} END {print "结束"}' awk_test.txt 开始123结束}
sed
类似”#查找出来包含root的行,并把它登录的shell显示出来[root@oldboy_50 tmp]# awk -F : '/root/ {print $7}' /etc/passwd/bin/bash/sbin/nologin#匹配以root开头的用户,并显示他的登录shell[root@oldboy_50 tmp]# awk -F : '/^root/ {print $7}' /etc/passwd/bin/bash#查找出不能登录的系统的用户,只显示文件名[root@oldboy_50 tmp]# awk -F : '/nologin$/ {print $1}' /etc/passwdbindaemonadm
awk有许多内置变量用来设置环境信息的,这些变量可以被改变
ARGC
命令行参数个数ARGV
ENVIRON
支持队列中系统环境变量的使用FILENAME
awk浏览的文件名(操作的文件名) [root@oldboy_50 ~]# awk 'BEGIN{FS=":";OFS="$" {print [root@oldboy_50 ~]# awk 'BEGIN{FS=":";OFS="$","\t"FILENAME}' /etc/passwd| head -3root /etc/passwdbin /etc/passwddaemon /etc/passwd}
FNR
浏览文件的记录数
FS
设置输入域分隔符,等价于命令-F 选项(分隔符) [root@oldboy_50 ~]# awk 'BEGIN{FS=":"} {print $1}' /etc/passwd| head -3rootbindaemon
NF
浏览记录的域的个数(列的个数)
NR
已读的记录数,记录行号(行)OFS
输出域分隔符 (输入分隔符) [root@oldboy_50 ~]# awk 'BEGIN{FS=":";OFS="$"} {print $1,$2}' /etc/passwd| head -3root$xbin$xdaemon$x
ORS
输出记录分隔符
RS
控制记录分隔符print
和printf
虽然这两个都是输出的意思,print是正常输出,printf可以带格式的输出其中print函数的参数可以是变量、数值或字符串。字符串必须用双引号,参数用逗号分隔,如果没有逗号,参数就串联在一起而无法区分。printf函数,其用法和C语言的printf基本像是。格式化复杂化输出 [root@oldboy_50 tmp]# awk '{print "filename:" FILENAME ",Linenumber" NR "file_link" $0}' /etc/passwd | head -2filename:/etc/passwd,Linenumber1file_linkroot:x:0:0:root:/root:/bin/bashfilename:/etc/passwd,Linenumber2file_linkbin:x:1:1:bin:/bin:/sbin/nologin
printf标准的格式化输出。
[root@oldboy_50 tmp]# awk '{printf("filename:%s;Linenumber:%d;file_line:%s\n",FILENAME,NR,$0)}' /etc/passwd | head -2filename:/etc/passwd;Linenumber:1;file_line:root:x:0:0:root:/root:/bin/bashfilename:/etc/passwd;Linenumber:2;file_line:bin:x:1:1:bin:/bin:/sbin/nologin
gsub
函数,替换函数相当于sed "s//g"
[root@oldboy_50 tmp]# cat 1.txt i am oldboy,dasasd 123[root@oldboy_50 tmp]# awk 'gsub(/,/," ",$3)' 1.txt | awk '{print $3,$5}'oldboy 123
sub
函数,相当于sed "s//"
,只替换匹配到的第一次把第一个域里面的内容替换成第二个
有一个文本文件data.test的内容如下:0001|20081223efskjfdj|EREADFASDLKJCV0002|20081208djfksdaa|JDKFJALSDJFsddf0003|20081208efskjfdj|EREADFASDLKJCV0004|20081211djfksdaa1234|JDKFJALSDJFsddf
以'|
'为分隔, 现要将第二个域字母前的数字去掉,其他地方都不变, 输出为:
0001|efskjfdj|EREADFASDLKJCV0002|djfksdaa|JDKFJALSDJFsddf0003|efskjfdj|EREADFASDLKJCV0004|djfksdaa1234|JDKFJALSDJFsddf
解决办法:
[root@oldboy_50 tmp]# awk -F "|" 'BEGIN{OFS="|";}sub(/[0-9]+/,"",$2)' 1.txt 0001|efskjfdj|EREADFASDLKJCV0002|djfksdaa|JDKFJALSDJFsddf0003|efskjfdj|EREADFASDLKJCV0004|djfksdaa1234|JDKFJALSDJFsddf
[root@oldboy_50 tmp]# awk 'BEGIN {count=0;print "count=0"} {count=count+1} END {print count}' /etc/passwdcount=024
查找登录SHELL是/bin/bash
的用户信息
[root@oldboy_50 ~]# awk -F':' '$NF=="/bin/bash"{print $0}' /etc/passwdroot:x:0:0:root:/root:/bin/bashzsf:x:500:500::/home/zsf:/bin/bash
方法二:
[root@oldboy_50 ~]# awk -F':' '/\/bin\/bash$/{print $0}' /etc/passwdroot:x:0:0:root:/root:/bin/bashzsf:x:500:500::/home/zsf:/bin/bash
方法三:
[root@oldboy_50 ~]# awk 'BEGIN {shell="/bin/bash";FS=":"} $NF==shell {print $0}' /etc/passwdroot:x:0:0:root:/root:/bin/bashzsf:x:500:500::/home/zsf:/bin/bash### `-n` 显示匹配到行的行号,和`cat -n`选项意思一样
[root@oldboy50 tmp]# grep -n "zsf" /etc/passwd
25:zsf:x:500:500::/home/zsf:/bin/bash### 正则表达#### `^str` 以什么字符串开头
[root@oldboy50 tmp]# cat >grep_file.txt<<EOF
zsf12
12zsf1212zsfEOF[root@oldboy50 tmp]# grep "zsf" grep_file.txt zsf1212zsf1212zsf[root@oldboy50 tmp]# grep "^zsf" grep_file.txt zsf12
str$
以什么字符串结尾[root@oldboy50 tmp]# grep "zsf$" grep_file.txt 12zsf
转载于:https://blog.51cto.com/13447608/2151867