前置文章
《Linux之shell编程》
《Linux命令汇总》
《2万字系统总结,带你实现 Linux 命令自由?》
《学习如何编写 Shell 脚本(基础篇)》
《学习如何编写 Shell 脚本(进阶篇)》
几个常用Linux命令总结
xargs
我们都知道,在Linux中,管道|
命令可以实现将左侧命令的标准输出转换为标准输入提供给右侧命令使用,但是有些命令不接受管道的传递方式,例如ls
、echo
等,其实有很多命令都不支持标准输入作为参数,只能在执行命令行时指定参数,这就导致不能使用管道|
命令传递参数。而xargs
命令的功能就是将标准输入进行处理,然后转化为命令行参数。
语法格式
command | xargs [options] command
常用参数如下:
-a file
:从文件中读入作为标准输入stdin
-d
:默认情况下,xargs
将换行符和空格作为分隔符,-d
可以更改分隔符-p
:打印要执行的命令,询问用户是否要执行-t
:打印要执行的命令,然后直接执行,不需要用户确认
使用实例
上面说到,有很多命令都不支持标准输入作为参数,导致不能使用管道|
命令传递参数,但是,xargs
和管道一起使用时,就可以了。
例如:
find 命令接受管道传递参数
find | grep test
# cat 命令不接受管道传递参数
cat test.txt
# hello xargs!
echo "test.txt" | cat
# test.txt
[root@centos7 test]#
# xargs 将标准输入转为命令行参数
echo "test.txt" | xargs cat
# hello xargs!
可以看到,cat
命令不接受管道传递参数,我们尝试通过标准输入把参数传给cat
, 结果只是显示了文件名 ,xargs
将echo
的输出作为标准输入传递给了右侧的cat
命令,作为命令的参数执行。
使用-d
参数指定制表符\t
作为分隔符:
echo -e "a\tb\tc" | xargs -d "\t" echo
# a b c
使用-p
参数打印要执行的命令,询问是否要执行:
find ./ | xargs -p rm -f
rm -f ./ ./test_ae ./test_ac ./test_am ?...
locate
搜索包含关键字的所有文件和目录。后接需要查找的文件名,也可以用正则表达式。
安装 locate
yum -y install mlocate --> 安装包
updatedb --> 更新数据库
locate file.txt
locate fil*.txt
[注意] locate
命令会去文件数据库中查找命令,而不是全磁盘查找,因此刚创建的文件并不会更新到数据库中,所以无法被查找到,可以执行 updatedb
命令去更新数据库。
which
which 查看可执行文件的位置。
find
用于查找文件,它会去遍历你的实际硬盘进行查找,而且它允许我们对每个找到的文件进行后续操作,功能非常强大。
find <路径> <选项> <操作>
- 路径:指定在哪个目录查找,此目录的所有子目录也会被查找。
- 选项:查找什么,可以根据文件的名字来查找,也可以根据其大小来查找,还可以根据其最近访问时间来查找。
- 操作:找到文件后,可以进行后续处理,如果不指定这个参数,
find
命令只会显示找到的文件。
参考文章:【链接】 《Linux 中使用 find 命令查找文件》
根据文件名查找
find -name "file.txt" --> 当前目录以及子目录下通过名称查找文件
find . -name "syslog" --> 当前目录以及子目录下通过名称查找文件
find . -iname "aa" --> 当前目录以及子目录下通过名称查找文件(忽略文件名字大小写)
find / -name "syslog" --> 整个硬盘下查找syslog
find /var/log -name "syslog" --> 在指定的目录/var/log下查找syslog文件
find /var/log -name "syslog*" --> 查找syslog1、syslog2 ... 等文件,通配符表示所有
find /var/log -name "*syslog*" --> 查找包含syslog的文件
根据文件大小查找
find /var -size +10M --> /var 目录下查找文件大小超过 10M 的文件
find /var -size -50k --> /var 目录下查找文件大小小于 50k 的文件
find /var -size +1G --> /var 目录下查找文件大小查过 1G 的文件
find /var -size 1M --> /var 目录下查找文件大小等于 1M 的文件
根据文件最近访问/修改时间查找
find -name "*.txt" -atime -7 --> 近 7天内访问过的.txt结尾的文件
find /home/admin/datax3/log/ -mtime +n --> n天外修改过的文件
find /home/admin/datax3/log/ -mtime -n --> n天内修改过的文件
仅查找目录或文件
find . -name "file" -type f --> 只查找当前目录下的file文件
find . -name "file" -type d --> 只查找当前目录下的file目录
操作查找结果
find -name "*.txt" -printf "%p - %u\n" --> 找出所有后缀为txt的文件,并按照 %p - %u\n 格式打印,其中%p=文件名,%u=文件所有者
find -name "*.jpg" -delete --> 删除当前目录以及子目录下所有.jpg为后缀的文件,不会有删除提示,因此要慎用
find -name "*.c" -exec chmod 600 {} \; --> 对每个.c结尾的文件,都进行 -exec 参数指定的操作,{} 会被查找到的文件替代,; 是必须的结尾
find -name "*.c" -ok chmod 600 {} \; --> 和上面的功能一直,会多一个确认提示
grep
全局搜索一个正则表达式,并且打印到屏幕。简单来说就是,在文件中查找关键字,并显示关键字所在行。
基础语法
grep text file # text代表要搜索的文本,file代表供搜索的文件
# 实例
[root@lion ~]# grep path /etc/profile
pathmunge () {
pathmunge /usr/sbin
pathmunge /usr/local/sbin
pathmunge /usr/local/sbin after
pathmunge /usr/sbin after
unset -f pathmunge
常用参数
-i
忽略大小写,grep -i path /etc/profile
-n
显示行号,grep -n path /etc/profile
-v
只显示搜索文本不在的那些行,grep -v path /etc/profile
-r
递归查找,grep -r hello /etc
,Linux 中还有一个 rgrep 命令,作用相当于grep -r
-F
不按照正则表达式匹配,按照字面意思匹配
高级用法
grep
可以配合正则表达式使用。
grep -E path /etc/profile --> 完全匹配path
grep -E ^path /etc/profile --> 匹配path开头的字符串
grep -E [Pp]ath /etc/profile --> 匹配path或Path
sed
stream Editor
的缩写,流编辑器,对标准输出或文件逐行进行处理。
语法格式
sed [option] "pattern/command" file
例如:
sed '/python/p' name.txt # 省略了option,/python/为pattern正则,p为command命令打印的意思
复制代码
[注意] 匹配模式中存在变量要使用双引号。
选项 option
-n
只打印模式匹配行
sed 'p' name.txt # 会对没一行字符串输出两遍,第一遍是原文本,第二遍是模式匹配到的文本
sed -n 'p' name.txt # 加了-n参数后就只打印模式匹配到的行
-e 默认选项
支持多个 pattern command
的形式
sed -e "pattern command" -e "pattern command" file
-f 指定动作文件
# 简单命令
sed -n '/python/p' name.txt # 但是一旦正则比较复杂,我们就可以把它保存在一个单独文件中,使用-f进行指定
# edit.sed 内容为 /python/p
sed -n -f edit.sed name.txt # '/python/p'这个命令保存在edit.sed文件中,使用-f指定
-E 扩展表达式
sed -n -E '/python|PYTHON/p' name.txt
-i 直接修改文件内容
sed -i 's/love/like/g' name.txt # -i修改原文件,全局love替换为like
模式匹配 pattern
pattern
用法表
匹配模式 | 含义 | 用法 |
---|---|---|
10command | 匹配到第10行 | sed -n "17p" name.txt 打印 name 文件的第17行 |
10,20command | 匹配从第10行开始,到第20行结束 | sed -n "10,20p" name.txt 打印 name 文件的10到20行 |
10,+5command | 匹配从第10行开始,到第15行结束 | sed -n "10,+5p" name.txt |
/pattern1/command | 匹配到 pattern1 的行 | sed -n "/^root/p" name.txt 打印 root 开头的行 |
/pattern1/,/pattern2/command | 匹配到 pattern1 的行开始,至匹配到 pattern2 的行结束 | sed -n "/^ftp/,/^mail/p" name.txt |
10,/pattern1/command | 匹配从第10行开始,到匹配到 pattern1 的行结束 | sed -n "4,/^ok/p" name.txt 打印 name 文件从第4行开始匹配,直到以 ok 开头的行结束 |
/pattern1/,10command | 匹配到 pattern1 的行开始,到第10行匹配结束 | sed -n "/root/,10p" name.txt |
命令 command
-
查询
p
-- 打印
-
增加
a
-- 行后追加i
-- 行前追加r
-- 外部文件读入,行后追加w
-- 匹配行写入外部文件
-
删除
d
-- 删除
-
修改
s/old/new
-- 将行内第一个old
替换为new
s/old/new/g
-- 将行内全部的old
替换为new
s/old/new/2g
--同一行,只替换从第二个开始到剩下所有的s/old/new/ig
-- 将行内old
全部替换为new
,忽略大小写
实例:
sed '/python/p' name.txt # 打印
sed '1d' name.txt # 删除第一行
sed -i '/frank/a hello' name.txt # 匹配到字符串frank就在这一行后面插入“hello”
sed -i '/frank/r list' name.txt # 把list文件内容追加到匹配frank字符串后面的行
sed -n '/frank/w tmp.txt' name.txt # 将匹配到frank的行全部写入tmp.txt文件中
sed -i 's/love/like/g' name.txt # 全局替换love为like,并修改源文件
反向应用
引用前面的匹配到的字符。
假设有一个文件 test.txt
内容为:
a heAAo vbv
c heBBo sdsad
k heCCo mnh
现在需要匹配到 heAAo heBBo heCCo
并在他们后面添加 s
。
使用反向引用可以这样做:
sed -i 's/he..o/&s/g' test.txt # 其中&就是引用前面匹配到的字符
sed -i 's/(he..o)/\1s/g' test.txt # 与上面的写法等价
# 输出结果
a heAAos vbv
c heBBos sdsad
k heCCos mnh
日志清理脚本
#!/bin/bash
echo "`date +"%Y-%m-%d %H:%M:%S"` start to clean log"
df -h | grep '/dev/vda1' | awk '{print $5}' | test $(sed 's/%//') -gt 80
if [ $? = 0 ]; then
find /home/admin/logs/ -type f -mtime +3 -exec rm -rf {} \;
find /home/admin/logs/ -type f -size +1G -exec rm -rf {} \;
fi
echo "`date +"%Y-%m-%d %H:%M:%S"` finish to clean log"
#!/bin/sh
df -h |grep '/dev/vdb' |awk '{print $5}'|test $((`sed 's/\%//'`)) -gt 60;
if [ $? = 0 ];then
for i in `find /mnt/disk1/log -type f -mtime +3`;
do echo '' > $i;
done
for i in `find /mnt/disk1/log -type f -type f -size +1G`;
do echo '' > $i;
done
fi
netstat练习1-查看各个状态的连接数
题目:链接
假设netstat命令运行的结果我们存储在nowcoder.txt里,格式如下:
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 0.0.0.0:6160 0.0.0.0:* LISTEN
tcp 0 0 127.0.0.53:53 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN
tcp 0 0 172.16.56.200:41856 172.16.34.144:3306 ESTABLISHED
tcp 0 0 172.16.56.200:49822 172.16.0.24:3306 ESTABLISHED
tcp 0 0 172.16.56.200:49674 172.16.0.24:3306 ESTABLISHED
tcp 0 0 172.16.56.200:42316 172.16.34.144:3306 ESTABLISHED
tcp 0 0 172.16.56.200:44076 172.16.240.74:6379 ESTABLISHED
tcp 0 0 172.16.56.200:49656 172.16.0.24:3306 ESTABLISHED
tcp 0 0 172.16.56.200:58248 100.100.142.4:80 TIME_WAIT
tcp 0 0 172.16.56.200:50108 172.16.0.24:3306 ESTABLISHED
tcp 0 0 172.16.56.200:41944 172.16.34.144:3306 ESTABLISHED
tcp 0 0 172.16.56.200:35548 100.100.32.118:80 TIME_WAIT
tcp 0 0 172.16.56.200:39024 100.100.45.106:443 TIME_WAIT
tcp 0 0 172.16.56.200:41788 172.16.34.144:3306 ESTABLISHED
tcp 0 0 172.16.56.200:58260 100.100.142.4:80 TIME_WAIT
tcp 0 0 172.16.56.200:41812 172.16.34.144:3306 ESTABLISHED
tcp 0 0 172.16.56.200:41854 172.16.34.144:3306 ESTABLISHED
tcp 0 0 172.16.56.200:58252 100.100.142.4:80 TIME_WAIT
tcp 0 0 172.16.56.200:49586 172.16.0.24:3306 ESTABLISHED
tcp 0 0 172.16.56.200:41754 172.16.34.144:3306 ESTABLISHED
tcp 0 0 172.16.56.200:50466 120.55.222.235:80 TIME_WAIT
tcp 0 0 172.16.56.200:38514 100.100.142.5:80 TIME_WAIT
tcp 0 0 172.16.56.200:49832 172.16.0.24:3306 ESTABLISHED
tcp 0 0 172.16.56.200:52162 100.100.30.25:80 ESTABLISHED
tcp 0 0 172.16.56.200:50372 172.16.0.24:3306 ESTABLISHED
tcp 0 0 172.16.56.200:50306 172.16.0.24:3306 ESTABLISHED
tcp 0 0 172.16.56.200:49600 172.16.0.24:3306 ESTABLISHED
tcp 0 0 172.16.56.200:41908 172.16.34.144:3306 ESTABLISHED
tcp 0 0 172.16.56.200:60292 100.100.142.1:80 TIME_WAIT
tcp 0 0 172.16.56.200:37650 100.100.54.133:80 TIME_WAIT
tcp 0 0 172.16.56.200:41938 172.16.34.144:3306 ESTABLISHED
tcp 0 0 172.16.56.200:49736 172.16.0.24:3306 ESTABLISHED
tcp 0 0 172.16.56.200:41890 172.16.34.144:3306 ESTABLISHED
udp 0 0 127.0.0.1:323 0.0.0.0:*
udp 0 0 0.0.0.0:45881 0.0.0.0:*
udp 0 0 127.0.0.53:53 0.0.0.0:*
udp 0 0 172.16.56.200:68 0.0.0.0:*
udp6 0 0 ::1:323 :::*
raw6 0 0 :::58 :::* 7
现在需要你查看系统tcp连接中各个状态的连接数,并且按照连接数降序输出。你的脚本应该输出如下:
ESTABLISHED 22
TIME_WAIT 9
LISTEN 3
结果命令:
grep "tcp" nowcoder.txt | awk '{print $6}' | sort | uniq -c | awk '{print $2, $1}' | sort -nr -k 2
打印1-500内 7 的倍数
$cat nowcoder.sh
#!/bin/bash
for i in {1..500}
do
if [ $(($i % 7)) == 0 ]
then
echo $i
fi
done