Linux 文本处理


Linux中很多文件都是文本文件,有很多工具用来处理文本文件。


awk

awk是模式扫描和处理语言,用于文本处理和生成报告。

awk命令的格式:

awk [-F 字段分隔符] [-v var=value] [程序] [文件...]

默认字段分隔符是空格。程序的格式是模式 { 动作 },如果文件中的行匹配到了模式(正则表达式),则执行对应的动作,如果省略动作,则执行print;如果省略模式,则表示所有行都匹配。

$ awk -F ':' '{ print $1 " " $7 }' /etc/passwd
$ awk -F ':' '{ print $1 " " $(NF) }' /etc/passwd
$ awk -F ':' '/root/ { print $1 " " $(NF) }' /etc/passwd

awk -F ':' '{ print $1 " " $7 }' /etc/passwd命令输出文件/etc/passwd中第1和第7个字段,使用空格分隔两个字段。

awk -F ':' '{ print $1 " " $(NF) }' /etc/passwd命令输出文件/etc/passwd中第1和第7个字段。NF是awk的内置变量,表示字段个数。文件/etc/passwd有7个字段,$(NF)等于$7$(NF-1)等于$6

awk -F ':' '/root/ { print $1 " " $(NF) }' /etc/passwd命令输出文件/etc/passwd中匹配正则表达式/root/的所有行的第1和第7个字段。

sed

sed命令(stream editor)读取指定文件,或标准输入(如果没指定文件),更改输入然后输出。

sed命令的格式:

sed [选项] command [文件...]

$ sed 's/java/js/g' file1
$ sed 's/java/js/' file1
$ sed '2s/java/js/g' file1
$ sed '1,3s/java/js/g' file1
$ sed '3!s/java/js/g' file1
$ sed '/3/s/java/js/g' file1
$ sed '2a\123' file1
$ sed '2i\123' file1
$ sed '2,4c\123' file1
$ sed '2,4d' file1
$ sed -n '2,4p' file1
$ sed '2=' file1

sed 's/java/js/g' file1命令将文件file1中每行的第一个java替换成js。

sed 's/java/js/' file1命令将文件file1中每行的java替换成js。

sed '2s/java/js/g' file1命令将文件file1中第2行的java替换成js。sed '2s/中的2是行号。

sed '2,5s/java/js/g' file1命令将文件file1中第2到第5行的java替换成js。

sed '3!s/java/js/g' file1命令将文件file1中除去第3行外的所有行的java替换成js。

sed '/abc/s/java/js/g' file1命令将文件file1中包含abc的所有行的java替换成js。sed '/abc/中的abc是正则表达式。

sed '2a\123' file1命令在文件file1的第2行后插入一行,写入123。

sed '2i\123' file1命令在文件file1的第2行前插入一行,写入123。

sed '2,4c\123' file1命令将文件file1中第2、3、4行的内容替换成123。

sed '2,4d' file1命令删除文件file1中第2、3、4行。

sed -n '2,4p' file1命令输出文件file1中第2、3、4行的内容。

sed '2=' file1命令在文件file1的第2行加上行号。不指定行号,则所有行都会加上行号。

常用的sed命令:

  • s/正则表达式/替换值/,将匹配正则表达式的内容替换成替换值
  • a,在当前行后附加内容
  • i,在当前行前插入内容
  • c,替换当前行的内容
  • d,删除当前行
  • p,打印当前行
  • =,输出当前行的行号

常用的sed地址(行号,或行范围):

  • n,行号,只能是正整数
  • n1,n2,第n1行和第n2行之间的所有行
  • n,+m,第n行和之后的m行
  • n~m,第n行开始,后面间隔m行的所有行
  • n!,除n行之外的所有行
  • $,最后一行
  • /正则表达式/,匹配正则表达式的所有行

tr

tr命令(translate)用来转换或删除字符。

tr命令的格式:

tr 转换前的字符集合 转换后的字符集合

字符集合有3种写法:

  • 字符列表,如abcd
  • 字符集合,如A-Z
  • 字符分类,如[:lower:]

tr命令例子:

$ echo apple | tr a-z A-Z
$ echo apple | tr ae 3
$ tr -d '\r' < file1 > file2

echo apple | tr a-z A-Z命令将小写字符更改成大写字符。

echo apple | tr ae 3命令将字符a和字符e更改成字符3。

tr -d '\r' < file1 > file2命令删除回车符(\r),用来将windows格式的文本文件转换成linux格式的文本文件。

cut

cut命令从指定文件的每一行中剪切指定部分的内容。默认使用tab作为分隔符。

$ cut -d : -f 1,7 /etc/passwd

cut -d : -f 1,7 /etc/passwd命令从文件/etc/passwd中剪切第1和第7列的内容,输出到屏幕。-d :表示使用:(冒号)作为列的分隔符。

diff

diff命令用来一行一行的比较文件。

$ diff file1 file2
$ diff -y -W 20 file1 file2
$ diff -c file1 file2
$ diff -u file1 file2

file1文件内容:

apple
pear
lemon
orange

file2文件内容:

banana
pear
orange
mongo

diff file1 file2命令的输出:

1c1
< apple
---
> banana
3d2
< lemon
4a4
> mongo

上面输出表示的是对文件file1进行哪些增、删、改操作,变成文件file2的过程。

1c1c(change)表示文件file1的第1行更改成文件file2的第1行,c前面的1表示文件file1中的行范围,c后面的1表示文件file2中的行范围。后面接着显示两个文件中第1行的内容的更改。

3d2,其中d(delete),表示删除文件file1中第3行的lemon。

4a4,其中a(add),表示在文件file1的第4行后面加上文件file2中第4行的mongo。

diff -y -W 20 file1 file2命令使用两列显示文件不同。

输出:

apple | banan
pear    pear
lemon <
orang   orang
      > mongo

|表示两个文件这行内容不同。<表示第1个文件有这行,第2个文件没有。>表示第1个文件没有这行,第2个文件有。

diff -c file1 file2命令使用上下文格式显示文件不同。

输出:

*** file1   2018-06-10 18:39:53.000000000 +0800
--- file2   2018-06-10 18:40:07.000000000 +0800
***************
*** 1,4 ****
! apple
  pear
- lemon
  orange
--- 1,4 ----
! banana
  pear
  orange
+ mongo

!表示两个文件这行内容不同。-表示第2个文件没有这行。+表示第1个文件没有这行。

diff -u file1 file2命令使用统一格式显示文件不同。

输出:

--- file1   2018-06-10 18:39:53.000000000 +0800
+++ file2   2018-06-10 18:40:07.000000000 +0800
@@ -1,4 +1,4 @@
-apple
+banana
 pear
-lemon
 orange
+mongo

统一格式表示的是对文件file1进行哪些更改(+-)操作,变成文件file2的过程。行前没有+-表示这行内容没有变化。-表示从文件file1中删除这行。+表示向文件file1中加入这行。