一、文本内容处理命令
1、数据流和重定向
1、数据流
- 标准输入(standard input,简称stdin):默认情况下,标准输入指从键盘获取的输入
- 标准输出(standard output,简称stdout):默认情况下,命令执行所回传正确的信息会输出到屏幕上
- 标准错误输出(standard error output,简称stderr):默认情况下,标准错误输出可理解为命令执行失败后,所回传的错误信息会输出到屏幕上
不管正确或错误的数据都是默认输出到屏幕上,所以屏幕是混乱的。所以就需要用数据流重定向将这两条数据分开。数据流重定向可以将标准输出和标准错误输出分别传送到其他的文件或设备去,而分别传送所用的特殊字符如下所示:
- 标准输入(stdin):代码为0
- 标准输出(stdout):代码为1
- 标准错误输出(stderr):代码为2
2、重定向操作符
重定向操作符可以将命令输入和输出数据流从默认设备重定向到其他位置。重定向操作符本身不是命令,而是命令中附加的可改变命令的输入和输出对象的特殊符号。
- 输出重定向操作符: > 、 >>
- 输入重定向操作符: < 、 <<
3、输出重定向案例
标准输出重定向: 1> 或 > 、 1>> 或 >>
标准错误输出重定向: 2> 、 2>>
案例1:输出重定向(覆盖)
[root@localhost ~]# date 1> date.txt
案例2:输出重定向(追加)
[root@localhost ~]# date >> date.txt
案例3:错误输出重定向
[root@localhost ~]# ls /home/ /aaaaaaaaa >list.txt
ls: 无法访问/aaaaaaaaa: 没有那个文件或目录
[root@localhost ~]# ls /home/ /aaaaaaaaa >list.txt 2>error.txt
#重定向到不同的位置
案例4: 正确和错误都输入到相同位置
[root@localhost ~]# ls /home/ /aaaaaaaaa &>list.txt
#混合输出
案例5: 正确和错误都输入到相同位置
[root@localhost ~]# ls /home/ /aaaaaaaaa >list.txt 2>&1
#重定向到相同的位置
案例6:重定向到空设备/dev/null
[root@localhost ~]# ls /home/ /aaaaaaaaa >list.txt 2>/dev/null
#空设备,即将产生的输出丢掉
[root@localhost ~]# ls /home/ /aaaaaaaaa &>/dev/null
#空设备,即将产生的输出丢掉
4、输入重定向案例
标准输入重定向: < 或 0< 、 0<< 或 <<
案例1:从文件读取数据作为cat命令的输入
[root@master ~]# echo test > file
[root@master ~]# cat < file
test
案例2:标准输入重定向 << 并不表示追加,而是表示输入结束的意思,即作为一个结束符。
[root@server ~]# cat > file3 << end
> china
> china
> hello
> end
[root@server ~]# cat file3
china
china
hello
# 输入end终止输入,不必输入ctrl+d来结束
拓展案例:
案例1:使用输入重定向写邮件
[root@localhost ~]# mail -s "ssss" alice
#没有改变输入的方向,默认键盘
111
222
333
^D
[root@localhost ~]# su - alice
[alice@localhost ~]$ mail
Mail version 8.1 6/6/93. Type ? for help.
"/var/spool/mail/alice": 1 message 1 new
\>N 1 root@localhost.local Mon Oct 29 14:09 18/657 "ssss"
&
[root@localhost ~]# mail -s "test01" alice < /etc/hosts #输入重定向,来自于文件
案例2:
[root@localhost ~]# dd if=/dev/zero of=/file1.txt bs=1M count=2
[root@localhost ~]# dd </dev/zero >/file2.txt bs=1M count=2
案例3:mysql表结构导入
[root@localhost ~]# mysql -uroot -p123 < bbs.sql
案例4:at
[root@localhost ~]# at now +5 min
at> useradd yang99
at> <EOT>
job 1 at 2015-06-09 11:57
[root@localhost ~]# vim at.txt
useradd yang100
useradd yang102
[root@localhost ~]# at now +2 min < at.txt
job 2 at 2015-06-09 11:55
拓展:使用文件描述符重定向的复杂用法
使用文件描述符的重定向都使用了&符号:
- cmd >&n 把输出送到文件描述符n
- cmd m>&n 把输出到文件符m的信息重定向到文件描述符n
- cmd >&- 关闭标准输出
- cmd <&n 输入来自文件描述符n
- cmd m<&n m来自文件描述符n
- cmd <&- 关闭标准输入
- cmd <&n- 移动输入文件描述符n而非复制它
- cmd >&n- 移动输出文件描述符 n而非复制它
示例 2>&1 :将stderr重定向到标准输出
2>&1 == &>
二、将标准输出重定向到文件
echo命令
-
作用:向终端设备上输出字符串或变量提取后的值
-
格式
echo "字符串"
echo "$量"
-
例:
[root@server ~]# echo "hello world"
[root@server ~]# str1="hello world"
[root@server ~]# echo "$str1"
hello world
[root@server ~]# num=1024
[root@server ~]# echo "$num"
1024
[root@server ~]# echo $SHELL
/bin/bash
将标准输出重定向到文件
[root@server ~]# echo "hello" > /root/test/file
[root@server ~]# echo "world" >> /root/test/file
扩展:
如果两种引号内是普通的标准字符,那是没有区别
但如果有特殊含义字符,下面区别
' ' :不会解释特殊字符含义,强引用
" " :会解释特殊字符含义,弱引用
补充:
[root@localhost ~]# echo 当前主机时间$`date` ``命令替换符
当前主机时间Sat Nov 26 14:56:27 CST 2022
root@localhost ~]# echo 当前主机时间$(date) $()命令替换符
当前主机时间Sat Nov 26 14:56:27 CST 2022
三、管道符:|
作用
-
管道符号,是unix一个很强大的功能,符号为一条竖线:"|",用于两个命令或者多个命令相连接,将管道符左边命令的输出作为管道符右边命令的输入
格式
命令A | 命令2 | 命令3 ……
例
[root@server ~]# more test1.txt | wc -l # 统计行数
5
[root@server ~]# cat /etc/group | tee test2.txt
[root@server ~]# cat /etc/group | tee test1.txt test2.txt
某些情况需要慎用管道符
-
编写命令计算字符串长度
# 法1:
[root@server ~]# time for i in {1..10000};do str1=`seq -s "nihao" 100`;echo ${#str1} &> /dev/null;done
real 0m21.439s
user 0m2.649s
sys 0m17.714s
# time计算耗时
# for 循环10000次
# seq生成nihao1、nihao2……nihao100
# 法2:通过管道符调用awk实现
[root@server ~]# time for i in {1..10000};do str1=`seq -s "haodao" 100`;echo "${str1}" | awk '{print length($0)}' &> /dev/null;done
real 0m55.732s
user 0m13.067s
sys 0m43.360s
-
结论:方法1所耗时最少,效率最高,方法2中结合了管道符的使用,耗时最多,效率最低,由于linux中的shell是由C语言开发的,因此它底层命令效率是最高的,而方法1中用的是linux内置命令,内置的操作;方法2通过管道符,这涉及到类似二次加工,效率肯定也就低了
tee命令读取数据输出到文件
tee命令
作用
-
读取标准输入的数据,并将其内容输出到文件的同时输出到屏幕(即想把输出保存到文件中,又想在屏幕上看到内容)
-
tee指令会从标准输入设备读取数据,将其内容输出到标准输出设备,同时输出到文件。
格式
tee 参数 文件名
参数
-
-a或--append,附加到现有文件的后面,而非覆盖它
-
-i或--ignore-interrupts 忽略中断信号
-
--help 在线帮助
例
[root@server ~]# tee test1.txt
aaa
aaa
bbb
bbb
ccc
ccc # 输入ccc并回车后按下ctrl+d 结束输入
[root@server ~]# cat test1.txt
aaa
bbb
ccc
[root@server ~]# tee -a test1.txt # 追加
123
123
456
456
[root@server ~]# cat test1.txt
aaa
bbb
ccc
123
456
四、切割显示-cut
作用
-
cut命令用于按列提取文本内容
格式
cut -d "分隔符" -f列数字 文件名
-c 字符 cut -c 1-4 剪切每一行第1-4个字符
-d 分割字符
-f 分割字段 第几个分隔字段,例:4-5个字段,包含分隔符
示例
-
/etc/passwd文件在保存用户数据信息时,每一项值之间是采用冒号来间隔的,如:
[root@server ~]# head 2 /etc/passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
-
基于“行”的方式来提取数据是比较简单的,只需要设置好要搜索的关键词即可,但如果按列搜索,不仅要使用-f参数来设置需要看的列数,还需要使用-d参数来设置间隔符号。
[root@kongd ~]# cut -d : -f1 /etc/passwd 每行:分隔的第一个字段
root
bin
daemon
adm
lp
-
例:提取内核版本号
[root@server ~]# uname -a | cut -d " " -f3
-
例:提取IP地址
[root@server ~]# ip a | grep ens160 | grep inet | cut -d "/" -f1 | cut -d " " -f6
# 注意空格
-
例:提取mac地址
[root@server ~]# ip a | grep link/ether | cut -d " " -f6
五、排序显示-sort
作用
-
sort命令用于对文本内容进行排序显示
格式:
sort -参数 文件名
参数
选项 | 作用 |
---|---|
-f | 忽略大小写 |
-b | 忽略缩进与空格 |
-n | 以数值型排序 |
-r | 反向排序 |
-u | 去除重复行 |
-t | 指定间隔符 |
-k | 设置字段范围 |
示例
-
sort命令执行后默认会按照字母顺序进行排序
[root@server ~]# cat fruit.txt
banana
pear
apple
orange
[root@server ~]# sort fruit.txt
apple
banana
orange
pear
[root@server ~]# cat /etc/passwd | cut -d : -f1 | sort # 取出所有账户名
-
sort -u参数进行去重操作:
[root@server ~]# cat sort.txt
Welcome to openlab.com
Red Hat certified
Welcome to openlab.com
Free Linux Lessons
Linux Course
[root@server ~]# sort -u sort.txt
Free Linux Lessons
Red Hat certified
Welcome to openlab.com
-
数字排序
[root@server ~]# cat number.txt
45
12
3
98
82
67
24
56
9
[root@server ~]# sort -n number.txt
[root@server ~]# sort -nr number.txt # 降序
-
下面的内容是节选自/etc/passwd文件中前五个字段的内容,并进行混乱排序后的样子:
[root@kongd ~]# cat user.txt
tss:x:59:59:Account used by the trousers package to sandbox the tcsd daemon
polkitd:x:998:996:User for polkitd
geoclue:x:997:995:User for geoclue
rtkit:x:172:172:RealtimeKit
pulse:x:171:171:PulseAudio System Daemon
qemu:x:107:107:qemu user
usbmuxd:x:113:113:usbmuxd user
unbound:x:996:991:Unbound DNS resolver
rpc:x:32:32:Rpcbind Daemon
gluster:x:995:990:GlusterFS daemons
-
上面其实是五个字段,各个字段之间是用了冒号进行间隔,如果想以第三个字段中的数字作为排序依据,那么就可以用-t参数指定间隔符,-k参数指定第几列,-n参数进行数字排序来搞定:
[root@server ~]# sort -t : -k 3 -n user.txt
rpc:x:32:32:Rpcbind Daemon
tss:x:59:59:Account used by the trousers package to sandbox the tcsd daemon
qemu:x:107:107:qemu user
usbmuxd:x:113:113:usbmuxd user
pulse:x:171:171:PulseAudio System Daemon
rtkit:x:172:172:RealtimeKit
gluster:x:995:990:GlusterFS daemons
unbound:x:996:991:Unbound DNS resolver
geoclue:x:997:995:User for geoclue
polkitd:x:998:996:User for polkitd
常用:#sort -nu aaa 将文件中的行按照数值从小到大显示,并且重复行只显示一次
六、去重显示-uniq
作用
-
uniq命令用于去除文本中连续的重复行(重复行必须相邻 )
格式
uniq -参数 文件名
-c 显示重复次数
-d 显示文件重复出现的内容
-D 显示所有重复行
示例
-
对比两个文本内容进行操作
[root@server ~]# cat uq1.txt
Welcome to openlab.com
Welcome to openlab.com
Welcome to openlab.com
Welcome to openlab.com
Red Hat certified
Free Linux Lessons
Professional guidance
Linux Course
[root@kongd ~]# uniq uq1.txt
Welcome to openlab.com
Red Hat certified
Free Linux Lessons
Professional guidance
Linux Course
七、文本内容统计wc
作用
-
wc命令用于统计指定文本文件的行数、字数(单词数)或字节数(默认每行后面有一个换行符)
格式
wc -参数 文件名
参数
选项 | 作用 |
---|---|
-l | 只显示行数 |
-w | 只显示单词数 |
-c | 只显示字节数 |
-m | 统计字符数 |
示例
-
统计所有
[root@server ~]# wc /etc/passwd
37 88 2083 /etc/passwd
# 行数 单词数 字节数
-
配合管道符计算
[root@server ~]# ll / | wc -l # 文件数
[root@server ~]# grep "/bin/bash" /etc/passwd | wc -l
[root@server ~]# cat /etc/passwd | cut -d ":" -f1 | wc -l
八、文件中字符替换显示-tr
作用
-
tr 指令从标准输入读取数据,经过替换或者删除后,将结果输出到标准输出
格式
tr -参数 替换内容 新内容
参数
-
-c :反选设定字符,符合 “替换内容” 的部份不做处理,不符合的剩余部份才进行转换
-
-d :删除指令字符
-
-s :缩减连续重复的字符成指定的单个字符
示例
-
小写字母全部转换成大写字母
[root@server ~]# cat /etc/passwd | tr a-z A-Z
-
提取IP地址
[root@server ~]# ip a | grep ens160 | grep inet | cut -d / -f1 | tr -s ' ' | cut -d ' ' -f3
例:
[root@localhost /]# echo helloworld | tr l 0 把l字符替换成0字符
he00owor0d
[root@localhost /]# echo helloworld | tr hl 0 把h以及l字符替换成0字符
[root@localhost /]# echo helloworld | tr l 01 把l字符替换成0字符
[root@localhost /]# echo helloworld | tr -t hl 0 等长字符替换;把h字符替换成0字符
[root@localhost /]# echo helloworld | tr -c l 0 反选定;除了l字符之外的字符替换成0字符
[root@localhost /]# echo helloworld | tr -d hl 删除字符;删除hl字符
[root@localhost /]# echo 1 2 3| tr -s " " " " 将多个连续重复字符替换为单个字符;
将多个连续重复的空格字符替换为单个空格字符
[root@localhost /]# df -h | tr -s " " " " | cut -d " " -f 4
九、文件内容过滤显示—grep
作用:
-
在指定的普通文件中查找并显示含有指定字符串的行,也可与管道符一起使用
格式
grep -参数 查找条件 文件名
参数
选项 | 说明 |
---|---|
-o | 只把查找的关键字显示出来 |
-c | 仅显示找到的行数 |
-i | 忽略大小写 |
-n | 显示行号 |
-v | 反向选择——仅列出没有“关键词”的行 |
-A | -A 2 搜索时显示匹配到的那一行以及下2行 |
-B | -B 2 搜索时显示匹配到的那一行以及上2行 |
-C | -C 2 搜索时显示匹配到的那一行以及上下2行 |
例:
grep 'root' /etc/passwd 过滤关键字,有root关键字行打印到终端
grep -o 'root' /etc/passwd 过滤关键字,只把root关键字打印到终端
grep -i 'ROOT' /etc/passwd 过滤关键字乎略大小写
grep -v 'root' /etc/passwd 过滤关键字,把没有关键字的行显示
#cat /etc/login.defs
grep -v '^#' /etc/login.defs ^#以#号开头
grep -v '^#' /etc/login.defs | grep -v '^$' ^$ 空白行