这里介绍在 linux
中的文本处理方法。
awk
sed
grep
wc
wc
Linux
wc
命令用于计算字数。
利用wc
指令我们可以计算文件的Byte数
、字数、或是列数,若不指定文件名称、或是所给予的文件名为 -
,则wc
指令会从标准输入设备读取数据。
wc [-clw][--help][--version][文件...]
-c
或--bytes
或--chars
只显示Bytes
数。-l
或--lines
只显示行数。-w
或--words
只显示字数。--help
在线帮助。--version
显示版本信息。
实例
在默认的情况下,wc
将计算指定文件的行数、字数,以及字节数。使用的命令为:
1 | wc testfile |
先查看testfile文件的内容,可以看到:
$ cat testfile
Linux networks are becoming more and more common, but scurity is often an overlooked
issue. Unfortunately, in today’s environment all networks are potential hacker targets,
fro0m tp-secret military research networks to small home LANs.
Linux Network Securty focuses on securing Linux in a networked environment, where the
security of the entire network needs to be considered rather than just isolated machines.
It uses a mix of theory and practicl techniques to teach administrators how to install and
use security applications, as well as how the applcations work and why they are necesary.
使用 wc
统计,结果如下:
$ wc testfile # testfile文件的统计信息
3 92 598 testfile # testfile文件的行数为3、单词数92、字节数598
其中,3
个数字分别表示testfile
文件的行数、单词数,以及该文件的字节数。
如果想同时统计多个文件的信息,例如同时统计testfile
、testfile_1
、testfile_2
,可使用如下命令:
1 | wc testfile testfile_1 testfile_2 #统计三个文件的信息 |
输出结果如下:
1 | wc testfile testfile_1 testfile_2 #统计三个文件的信息 |
统计进程行数
1 | ps -e | wc -l |
sed
ps: 该命令的执行方式在 linux
中和 MacBook
表现不一样。
Linux sed
命令是利用脚本来处理文本文件。
sed
可依照脚本的指令来处理、编辑文本文件。
Sed
主要用来自动编辑一个或多个文件、简化对文件的反复操作、编写转换程序等。
sed [-hnV][-e<script>][-f<script文件>][文本文件]
-e<script>
或--expression=<script>
以选项中指定的script
来处理输入的文本文件。-f<script文件>
或--file=<script文件>
以选项中指定的script
文件来处理输入的文本文件。-h
或--help
显示帮助。-n
或--quiet
或--silent
仅显示script
处理后的结果。-V
或--version
显示版本信息。
动作说明:
a
:新增,a
的后面可以接字串,而这些字串会在新的一行出现(目前的下一行)~c
:取代,c
的后面可以接字串,这些字串可以取代n1
,n2
之间的行!d
:删除,因为是删除啊,所以d
后面通常不接任何咚咚;i
:插入,i
的后面可以接字串,而这些字串会在新的一行出现(目前的上一行);p
:打印,亦即将某个选择的数据印出。通常p
会与参数sed -n
一起运行~s
:取代,可以直接进行取代的工作哩!通常这个s
的动作可以搭配正规表示法!例如1,20s/old/new/g
就是啦!
实例
在testfile
文件的第四行后添加一行,并将结果输出到标准输出,在命令行提示符下输入如下命令:
sed -e 4a\newLine testfile
sed -e
没有 -e
也行啦!同时也要注意的是,sed
后面接的动作,请务必以 ''
两个单引号括住喔!
sed '4a newLine' testfile # 效果和上面相同
以行为单位的新增/删除
将 /etc/passwd
的内容列出并且列印行号,同时,请将第 2~5
行删除!
nl /etc/passwd | sed '2,5d'
只要删除第 2
行
nl /etc/passwd | sed '2d'
要删除第 3
到最后一行
nl /etc/passwd | sed '3,$d'
在第二行前写东西
nl /etc/passwd | sed '2i drink tea'
增加多行
nl /etc/passwd | sed '2a Drink tea or ......\
> drink beer ?'
命令行中有 \
的时候,指可以继续向下写,每一行之间都必须要以反斜杠『 \
』来进行新行的添加喔!
具体到某一段添加
nl test | sed '/i21/a\55'
在行为 i21
后面添加 55
以行为单位的替换与显示
将第2-5
行的内容取代成为No 2-5 number
呢?
nl /etc/passwd | sed '2,5c No 2-5 number'
透过这个方法我们就能够将数据整行取代了!
仅列出 /etc/passwd
文件内的第 5-7
行
nl /etc/passwd | sed -n '5,7p'
数据的搜寻并显示
搜索 /etc/passwd
有root
关键字的行
nl /etc/passwd | sed '/root/p'
如果root
找到,除了输出所有行,还会输出匹配行。
使用-n
的时候将只打印包含模板的行。
比如,一个文件 test
内容如下
1 | i21 |
执行
nl test | sed '/21/p'
输出
1 | 1 i21 |
执行
nl test | sed -n '/21/p'
输出
1 | 1 i21 |
数据的搜寻并删除
删除/etc/passwd
所有包含root
的行,其他行输出
nl /etc/passwd | sed '/root/d'
数据的搜寻并执行命令
搜索/etc/passwd
,找到root
对应的行,执行后面花括号中的一组命令,每个命令之间用分号分隔,这里把bash
替换为blueshell
,再输出这行:
nl /etc/passwd | sed -n '/root/{s/bash/blueshell/;p;q}'
最后的q
是退出。
这个命令我没执行成功。
数据的搜寻并替换
除了整行的处理模式之外, sed
还可以用行为单位进行部分数据的搜寻并取代。基本上 sed
的搜寻与替代的与 vi
相当的类似!他有点像这样:
sed 's/要被取代的字串/新的字串/g'
先观察原始信息,利用 /sbin/ifconfig
查询 IP
命令
ifconfig eno1
1 | eno1 Link encap:Ethernet HWaddr ac:1f:6b:26:4d:fc |
命令
/sbin/ifconfig eno1 | grep 'inet addr'
输出
1 | inet addr:219.244.171.32 Bcast:219.244.171.127 Mask:255.255.255.128 |
命令
/sbin/ifconfig eno1 | grep 'inet addr'|sed 's/^.*addr://g'
输出
1 | 219.244.171.32 Bcast:219.244.171.127 Mask:255.255.255.128 |
命令
/sbin/ifconfig eno1 | grep 'inet addr'|sed 's/^.*addr://g' | sed 's/Bca.*$//g'
输出
1 | 219.244.171.32 |
多点编辑
一条sed
命令,删除/etc/passwd
第三行到末尾的数据,并把bash
替换为blueshell
nl /etc/passwd | sed -e '3,$d' -e 's/bash/blueshell/'
直接修改文件内容
利用 sed
将 regular_express.txt
内每一行结尾若为 .
则换成 !
sed -i 's/\.$/\!/g' regular_express.txt
利用 sed
直接在 regular_express.txt
最后一行加入 # This is a test
:
sed -i '$a # This is a test' regular_express.txt
由於 $
代表的是最后一行,而 a
的动作是新增,因此该文件最后新增 # This is a test!
sed
的 -i
选项可以直接修改文件内容,这功能非常有帮助!举例来说,如果你有一个 100 万行的文件,你要在第 100 行加某些文字,此时使用 vim
可能会疯掉!因为文件太大了!那怎办?就利用 sed
啊!透过 sed
直接修改/取代的功能,你甚至不需要使用 vim
去修订!
grep
grep(global search regular expression(RE) and print out the line
,全面搜索正则表达式并把行打印出来)是一种强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹配的行打印出来。
选项 | 作用 |
---|---|
-a | 不要忽略二进制数据。 |
-A | <显示列数> 除了显示符合范本样式的那一行之外,并显示该行之后的内容。 |
-b | 在显示符合范本样式的那一行之外,并显示该行之前的内容。 |
-c | 计算符合范本样式的列数。 |
-C | <显示列数>或-<显示列数> 除了显示符合范本样式的那一列之外,并显示该列之前后的内容。 |
-d | <进行动作> 当指定要查找的是目录而非文件时,必须使用这项参数,否则grep命令将回报信息并停止动作。 |
-e | <范本样式> 指定字符串作为查找文件内容的范本样式。 |
-E | 将范本样式为延伸的普通表示法来使用,意味着使用能使用扩展正则表达式。 |
-f | <范本文件> 指定范本文件,其内容有一个或多个范本样式,让grep查找符合范本条件的文件内容,格式为每一列的范本样式。 |
-F | 将范本样式视为固定字符串的列表。 |
-G | 将范本样式视为普通的表示法来使用。 |
-h | 在显示符合范本样式的那一列之前,不标示该列所属的文件名称。 |
-H | 在显示符合范本样式的那一列之前,标示该列的文件名称。 |
-i | 忽略字符大小写的差别。 |
-l | 列出文件内容符合指定的范本样式的文件名称。 |
-L | 列出文件内容不符合指定的范本样式的文件名称。 |
-n | 在显示符合范本样式的那一列之前,标示出该列的编号。 |
-q | 不显示任何信息。 |
-R/-r | 此参数的效果和指定“-d recurse”参数相同。 |
-s | 不显示错误信息。 |
-v | 反转查找。 |
-w | 只显示全字符合的列。 |
-x | 只显示全列符合的列。 |
-y | 此参数效果跟“-i”相同。 |
-o | 只输出文件中匹配到的部分。 |
在文件中搜索一个单词,命令会返回一个包含“match_pattern
”的文本行:
grep match_pattern file_name
grep "match_pattern" file_name
在多个文件中查找:
grep "match_pattern" file_1 file_2 file_3 ...
输出除之外的所有行 -v
选项:
grep -v "match_pattern" file_name
标记匹配颜色 --color=auto
选项:
grep "match_pattern" file_name --color=auto
使用正则表达式 -E
选项:
grep -E "[1-9]+"
或
egrep "[1-9]+"
只输出文件中匹配到的部分 -o
选项:
echo this is a test line. | grep -o -E "[a-z]+\."
line.
echo this is a test line. | egrep -o "[a-z]+\."
line.
统计文件或者文本中包含匹配字符串的行数 -c
选项:
grep -c "text" file_name
输出包含匹配字符串的行数 -n
选项:
grep "text" -n file_name
或
cat file_name | grep "text" -n
#多个文件
grep "text" -n file_1 file_2
打印样式匹配所位于的字符或字节偏移:
echo gun is not unix | grep -b -o "not"
7:not
一行中字符串的字符便宜是从该行的第一个字符开始计算,起始值为 0
。选项 -b
-o
一般总是配合使用。
搜索多个文件并查找匹配文本在哪些文件中:
grep -l "text" file1 file2 file3...
grep递归搜索文件
在多级目录中对文本进行递归搜索:
grep "text" . -r -n
# .表示当前目录。
忽略匹配样式中的字符大小写:
echo "hello world" | grep -i "HELLO"
hello
选项 -e
制动多个匹配样式:
echo this is a text line | grep -e "is" -e "line" -o
is
line
#也可以使用-f选项来匹配多个样式,在样式文件中逐行写出需要匹配的字符。
cat patfile
aaa
bbb
echo aaa bbb ccc ddd eee | grep -f patfile -o
在grep
搜索结果中包括或者排除指定文件:
#只在目录中所有的.php和.html文件中递归搜索字符"main()"
grep "main()" . -r --include *.{php,html}
#在搜索结果中排除所有README文件
grep "main()" . -r --exclude "README"
#在搜索结果中排除filelist文件列表里的文件
grep "main()" . -r --exclude-from filelist
使用0
值字节后缀的grep
与xargs
:
#测试文件:
echo "aaa" > file1
echo "bbb" > file2
echo "aaa" > file3
grep "aaa" file* -lZ | xargs -0 rm
#执行后会删除file1和file3,grep输出用-Z选项来指定以0值字节作为终结符文件名(\0),xargs -0 读取输入并用0值字节终结符分隔文件名,然后删除匹配文件,-Z通常和-l结合使用。
grep
静默输出:
grep -q "test" filename
#不会输出任何信息,如果命令运行成功返回0,失败则返回非0值。一般用于条件测试。
打印出匹配文本之前或者之后的行:
#显示匹配某个结果之后的3行,使用 -A 选项:
seq 10 | grep "5" -A 3
5
6
7
8
#显示匹配某个结果之前的3行,使用 -B 选项:
seq 10 | grep "5" -B 3
2
3
4
5
#显示匹配某个结果的前三行和后三行,使用 -C 选项:
seq 10 | grep "5" -C 3
2
3
4
5
6
7
8
#如果匹配结果有多个,会用“--”作为各匹配结果之间的分隔符:
echo -e "a\nb\nc\na\nb\nc" | grep a -A 1
a
b
--
a
b