本篇主要讲管道及 Filter 的使用
目录
引号的使用
使用引号以去掉特殊字符的特殊含义(# $ \ etc.)
有三种去掉特殊含义的方式:反斜杠 \ 单引号' 双引号"
- 反斜杠 \ 的使用
类似于转义,去掉反斜杠右边第一个特殊符号的特殊含义
(base) 123deiMac:~ a123$ var=1
(base) 123deiMac:~ a123$ echo $var
1
(base) 123deiMac:~ a123$ echo \$var
$var
早期的 linux 系统因为屏幕的命令行是定长的,有时命令太长一行写不下,使用 \ 说明这是跨行的命令
(base) 123deiMac:~ a123$ echo hh \
> j
hh j
(base) 123deiMac:~ a123$ echo hh \\
hh \
- 单引号 ' 的使用
单引号会去掉引号内所有特殊字符的特殊含义,也就是说单引号内的都是一个常量,是一个字符串或常数之类的
- 双引号 " 的使用(比单引号更常用)
去掉引号内特殊字符的含义,除了下列四种情况,也就是保留下列四种情况的特殊含义
1、反斜杠 \
2、${variable name}
3、 ${command}
4、`command`
这四种情况是的我们可以变量套变量,编程更灵活
看下列一段代码,比较单引号和双引号的使用
(base) 123deiMac:~ a123$ var0=1
(base) 123deiMac:~ a123$ var1='$var0' # 字符串常量$var0
(base) 123deiMac:~ a123$ var2="$var0" # 变量等于var0
(base) 123deiMac:~ a123$ echo $var1 $var2
$var0 1
Filter
Filter 是一类命令的集合
Filter 读取标准输入并生成标准输出,过滤器把输入流的内容或文件发送给屏幕终端,而不会修改输入流/文件
常用的 Filter :cat grep sort wc
输出重定向
输出重定向就是把命令的结果写入文件(而非输出在屏幕上)
- 使用 > 或者 >> 输出重定向
Creat/overwrite # 不存在则创建,存在则覆盖
$ date > date.out
$ ls > list.txt
Creat/append # 不存在则创建,存在则追加至尾部
$ data >> data.out
$ ls >> list.txt
- 使用 - 2> 或者 2>> 输出重定向
用来把错误输出到文件
如果程序要跑很长时间才能出结果,可以用 -2> 或 2>> 输出重定向
输入重定向
使用 < 或 <<进行输入重定向
如果和输出重定向分不清楚的话,就把大于小于号看成一个漏斗,大的往小的方向去
查找 file 文件中的含有 orange 的行并排序不重复的输出
grep orange < ./file |sort|uniq|wc -l
其中的 | 是管道
管道
将某个命令执行返回的内容作为下一个命令的输入
用 | 来表示
如在 ps -ef 的返回结果中查找有 pycharm 的
ps -ef|grep pycharm
管道可以多次叠加
cut
按照指定字符对字符串进行分割
经常跟在管道后面使用
(base) 123deiMac:ttt a123$ who
a123 console May 7 08:07
a123 ttys000 May 7 09:53
(base) 123deiMac:ttt a123$ who|cut -f1 -d ' '
a123
a123
sed
对一段文本处理后,将处理的结果取走而不改变原文
与 vi 不同的是 sed 可以过滤来自管道的输出
sed 的命令比较多,这里只说比较简单的一些
- p(print)打印操作
# 显示 myfile 文件的全部内容
$ sed -n p myfile
# 显示 myfile 文件中第 5 行的内容
$ sed -n 5p myfile
# 显示 myfile 文件中最后一行的内容
$ sed -n '$p' myfile
# 显示 myfile 文件从第 3 行开始步长为5的行的内容
$ sed -n 3~5p myfile
$ sed -n 3~5= myfile
# 显示 myfile 文件从第 3 行开始到第 10 行的内容
$ sed -n 3,10p myfile
# 显示 myfile 文件第 10 行及其后的 10 行内容
$ sed -n 3,+10p myfile
# 显示 myfile 文件从第 3 行开始到最后一行的内容
$ sed -n '3,$p' myfile
# 显示 myfile 文件中所有包含 LANG 的行
$ sed -n /LANG/p myfile
# 显示 myfile 文件中所有不包含 LANG 的行
$ sed -n '/LANG/!p' myfile
- s(substitude)替换操作
# 在每个输入行中, 将第一个出现的 Windows 替换为 Linux
$ sed 's/Windows/Linux/' myfile
# 在每个输入行中, 将第一个出现的 Windows 替换为 Linux ,打印替换结果的行
$ sed -n 's/Windows/Linux/p' myfile
# 在每个输入行中, 将出现的每个 Windows 替换为 Linux, g 意为 global
$ sed 's/Windows/Linux/g' myfile
# 在每个输入行中, 将出现的每个 Windows 替换为 Linux ,打印替换结果的行
$ sed -n 's/Windows/Linux/g' myfile
# 在每个输入行中, 将出现的每个 Unix 替换为 Unix/Linux(&表示匹配到的字符串)
$ sed -e 's/Unix/&\/Linux/g' myfile
# 将所有连续出现的c都压缩成单个的c
$ sed 's/cc*/c/g' myfile
# 删除行首的一个空格
$ sed 's/ //' myfile
# 删除每一行前导的连续“空白字符”(空格,制表符)
$ sed 's/^[ \t]*//' myfile
# 删除以句点结尾的行中末尾的句点
$ sed 's/\.$//g' myfile
# 删除每行的第一个字符
$ sed 's/.//' myfile
- d(delete)操作
# 删除所有空白行
$ sed '/^$/d' myfile
$ sed '/./!d' myfile
# 删除掉所有包含"GUI"的行
$ sed '/GUI/d' myfile
awk
对文本的分析工具
不只是 grep 的单纯匹配文本
还能做更复杂的正则、分割、浮点运算等格式化匹配输出
更多 shell 中的变量与数值运算详见这里
给出一段例程
# 使用awk打印字符串
$ awk 'BEGIN { print "hello" }' hello
# 使用awk进行浮点运算
$ awk 'BEGIN { print 1.05e+2/10.5+2.0**3-3.14 }' 14.86
# 显示要处理的输入文件
$ cat test.txt
F115!16201!1174113017250745 10.86.96.41 211.140.16.1 200703180718
F125!16202!1174113327151715 10.86.96.42 211.140.16.2 200703180728
F235!16203!1174113737250745 10.86.96.43 211.140.16.3 200703180738
F245!16204!1174113847250745 10.86.96.44 211.140.16.4 200703180748
F355!16205!1174115827252725 10.86.96.45 211.140.16.5 200703180758
# 显示输入文件的内容
$ awk {print} test.txt
F115!16201!1174113017250745 10.86.96.41 211.140.16.1 200703180718
F125!16202!1174113327151715 10.86.96.42 211.140.16.2 200703180728
F235!16203!1174113737250745 10.86.96.43 211.140.16.3 200703180738
F245!16204!1174113847250745 10.86.96.44 211.140.16.4 200703180748
F355!16205!1174115827252725 10.86.96.45 211.140.16.5 200703180758
# 使用正则表达式匹配行,{actions} 省略时表示 { print }
$ awk '/F[12].*/' test.txt
F115!16201!1174113017250745 10.86.96.41 211.140.16.1 200703180718
F125!16202!1174113327151715 10.86.96.42 211.140.16.2 200703180728
F235!16203!1174113737250745 10.86.96.43 211.140.16.3 200703180738
F245!16204!1174113847250745 10.86.96.44 211.140.16.4 200703180748
# 使用正则表达式匹配行,并打印匹配的第1和第3列(域、字段)
$ awk '/^F[12].*/ {print $1,$3}' test.txt
F115!16201!1174113017250745 211.140.16.1
F125!16202!1174113327151715 211.140.16.2
F235!16203!1174113737250745 211.140.16.3
F245!16204!1174113847250745 211.140.16.4
# 更改字段分隔符为! ,执行上面的操作
$ awk -F\! '/^F[12].*/ {print $1,$3}'test.txt
F115 1174113017250745 10.86.96.41 211.140.16.1 200703180718
F125 1174113327151715 10.86.96.42 211.140.16.2 200703180728
F235 1174113737250745 10.86.96.43 211.140.16.3 200703180738
F245 1174113847250745 10.86.96.44 211.140.16.4 200703180748
需要掌握,不难
# 提取文件 test.txt 中的手机号
$ cat test.txt | awk -F\! '{print $3}' | awk '{print $1}'|cut 13017250745
13327151715
13737250745
13847250745
15827252725
wc
统计文件的行数、单词数和字节数
使用方法
wc file1 file2 file3
xargs
经常跟在管道后使用
因为有些命令不支持管道只能用命令来调用
xargs 可以单独使用
也可以表示对前一个命名执行 xargs 后的命令
以下两个命令是等价的
ls *.txt|xargs rm
rm *.txt
再看一个例子
$ more 31.sh echo $1 $2 $3
$ 31.sh 11 22 33
11 22 33
$ echo 11 22 55 | xargs 31.sh
11 22 55
这个例子说明 xargs 可以完成参数的传递
也就是说 echo 11 22 55 | xargs 31.sh 和 31.sh 11 22 33 是等价的
更多的常用例子
$ cat url-list.txt | xargs wget -c # 假如你有一个文件包含了很多你希望下载的 URL,可以使用 xargs 下载所有链接
# 希望取出 passwd 中前三行的用户名,并用 id 命令显示每个用户的信息
$ id $(cut -d ':' -f 1 /etc/passwd | head -n 3) # 错误
$ cut -d ':' -f 1 /etc/passwd | head -n 3 | id # 一样达不到目的
$ cut -d ':' -f 1 /etc/passwd | head -n 3 | xargs -n 1 id # 没问题
tr
替换/压缩文本
可选项 -s 表示对该字符的压缩
可选项 -d 表示对该字符的删除
$ tr –s “ ” < filename # 把多个空格压缩为一个空格
$ tr -s " " < filename > filename.tr # 将压缩空格后的文件内容写入到文件中
$ more passwd | tr [:lower:] [:upper:] # 列出passwd这个文件内容并将其中小写变大写输出
$ tr [:lower:] [:upper:] < passwd # 输入重定向的方法,功能同上一条命令
$ tr -d "ss" < filename # 删除fielname文件中的字符串ss
tee
我们已经知道如何把命令的结果打印到屏幕(直接运行)或输出到文件(输出重定向)
有时需要一边在屏幕打印一边写入到文件
方法一:需要打开两个字符终端
# 终端1
$ ./1.sh > output.txt
# 终端2
$ tail -f output.txt
方法二:只用开一个字符终端
$ ./1.sh | tee output.txt
tar
linux 中的常用解压缩工具
压缩
# touch a.c
# tar -czvf test.tar.gz a.c //压缩 a.c文件为test.tar.gz
a.c
查看压缩文件内容
# tar -tzvf test.tar.gz
-rw-r--r-- root/root 0 2010-05-24 16:51:59 a.c
解压
# tar -xzvf test.tar.gz
a.c
菜鸟教程 - Linux tar.gz、tar、bz2、zip 等解压缩、压缩命令详解