Linux文本处理三剑客 - grep sed awk
1. 基本用法
grep
是一种强大的文本搜索工具,用于在文件中搜索指定的模式(通常是字符串或正则表达式),并输出匹配的行。以下是 grep
的一些基本用法:
基本语法
bash
grep [选项] 模式 [文件...]
常用选项
-i
:忽略大小写。-v
:反向选择,显示不包含匹配模式的行。-c
:计算匹配的行数。-l
:显示包含匹配模式的文件名。-L
:显示不包含匹配模式的文件名。-n
:显示匹配的行号。-H
:显示文件名(在搜索多个文件时默认启用)。-h
:不显示文件名(在搜索多个文件时)。-r
或-R
:递归搜索目录中的文件。-w
:只匹配整个单词。-x
:只匹配整行。-A NUM
:显示匹配行及其后 NUM 行。-B NUM
:显示匹配行及其前 NUM 行。-C NUM
:显示匹配行及其前后各 NUM 行。-E
或--extended-regexp
:使用扩展正则表达式。-F
或--fixed-strings
:将模式视为固定字符串(不使用正则表达式)。-P
或--perl-regexp
:使用 Perl 兼容正则表达式。
模式
模式可以是简单的字符串,也可以是正则表达式。
示例
- 在文件中搜索字符串 "hello":
bash
grep "hello" filename.txt
- 忽略大小写搜索 "hello":
bash
grep -i "hello" filename.txt
- 显示包含 "hello" 的文件名:
bash
grep -l "hello" *.txt
- 递归搜索目录中的所有文件(包括子目录):
bash
grep -r "hello" /path/to/directory
- 显示匹配 "hello" 的行号:
bash
grep -n "hello" filename.txt
- 显示匹配 "hello" 的行及其后两行:
bash
grep -A 2 "hello" filename.txt
- 使用扩展正则表达式搜索模式(例如,匹配以 "foo" 开头,后跟任意字符,再以 "bar" 结尾的字符串):
bash
grep -E "^foo.*bar$" filename.txt
请注意,grep
的输出通常默认会打印到标准输出(通常是终端或控制台)。如果你希望将输出保存到文件中,可以使用重定向操作符 >
,例如:
bash
grep "hello" filename.txt > output.txt
这样,grep
的输出就会被保存到 output.txt
文件中,而不是显示在终端上。
2. sed
sed
是一款流式文本编辑器,它允许你对文本进行过滤和转换。以下是 sed
的基本用法和一些常见操作的示例:
基本语法
bash
sed [option] '地址定位+sed指令' filename
option
:sed命令的选项,用于控制sed的行为。地址定位
:决定对哪些行进行编辑。可以是行号、正则表达式或空(表示所有行)。sed指令
:指定要对匹配的行执行的操作,如打印、删除、替换等。filename
:要处理的文件名。
常用选项
-r
或--regexp-extended
:启用扩展正则表达式。-e
:允许在同一命令行上执行多个脚本。-n
:取消默认输出,只输出处理过的行。-i
:直接修改文件内容,而不是输出到标准输出。
地址定位
- 行号:如
1
表示第一行,$
表示最后一行。 - 正则表达式:如
/pattern/
表示匹配包含该模式的行。 - 空:表示对所有行进行操作。
常见指令
p
:打印匹配的行。d
:删除匹配的行。s
:替换匹配的内容。格式为s/原字符串/新字符串/[修饰符]
。i
:在匹配行前插入新行。a
:在匹配行后追加新行。c
:替换匹配行。
示例
- 打印文件内容 (默认行为,通常不需要使用
-p
,除非与-n
结合使用):
bash
sed '' filename
或
bash
sed -n 'p' filename
- 删除第一行:
bash
sed '1d' filename
- 删除最后一行:
bash
sed '$d' filename
- 删除第2到第4行:
bash
sed '2,4d' filename
- 打印第2到第4行:
bash
sed -n '2,4p' filename
- 替换所有 "foo" 为 "bar":
bash
sed 's/foo/bar/g' filename
- 在包含 "pattern" 的行前插入 "new line":
bash
sed '/pattern/i\new line' filename
- 在包含 "pattern" 的行后追加 "new line":
bash
sed '/pattern/a\new line' filename
- 使用扩展正则表达式(例如,匹配以 "foo" 开头的行):
bash
sed -r '/^foo/' filename
- 直接修改文件(将 "foo" 替换为 "bar" 并保存到原文件):
bash
sed -i 's/foo/bar/g' filename
请注意,sed
的操作是基于流的,这意味着它逐行处理输入数据。因此,对于大型文件,sed
通常比逐行读取和处理文件的脚本更高效。
3. awk
awk
是一个强大的文本处理工具,它特别适用于对列式数据进行处理和分析。以下是 awk
的基本用法和一些常见的示例:
基本语法
bash
awk 'pattern { action }' input-file
pattern
:这是可选的,表示要搜索的模式。如果省略,awk
会对每一行都执行action
。action
:这是awk
执行的命令,用花括号{}
包围。input-file
:这是awk
要处理的输入文件。
常见选项
-F fs
:指定输入字段分隔符为fs
。-v var=value
:在awk
程序中设置一个变量及其值。-f program-file
:从指定的文件中读取awk
程序。
内建变量
$0
:整行文本。$1, $2, ...
:每行的第一个、第二个等字段。NF
:字段数量。NR
:当前记录(行)号。FS
:输入字段分隔符(默认为空格或制表符)。OFS
:输出字段分隔符(默认为空格)。
示例
-
打印文件的所有行
bashawk '{ print }' input.txt
这实际上与
cat input.txt
相同,但awk
更适合进行更复杂的文本处理。 -
打印文件的特定字段
bashawk '{ print $1, $3 }' input.txt
这将打印每行的第一个和第三个字段。
-
使用字段分隔符
如果字段由逗号分隔,可以使用
-F
选项:bashawk -F, '{ print $1, $3 }' input.csv
-
条件匹配
bashawk '$3 > 100 { print $1, $3 }' input.txt
这将打印第三个字段大于100的行的第一个和第三个字段。
-
设置输出字段分隔符
bashawk 'BEGIN { OFS="," } { print $1, $3 }' input.txt
这将使用逗号作为输出字段分隔符。
-
使用变量
bashawk -v threshold=100 '$3 > threshold { print $1, $3 }' input.txt
这里,
threshold
是一个变量,其值在awk
程序外部设置。 -
从文件中读取
awk
程序bashawk -f script.awk input.txt
script.awk
文件包含要执行的awk
程序。
注意事项
awk
程序中的花括号{}
内的语句应该以分号;
或换行符分隔。- 在
BEGIN
块中,可以在处理任何输入行之前执行初始化代码。 - 在
END
块中,可以在处理完所有输入行之后执行清理代码。
awk
是一个功能非常强大的工具,上述只是其基本用法的介绍。通过组合不同的模式和动作,awk
可以用于解决各种复杂的文本处理任务。