grep

在 etc/passwd 中查找

grep

Search in /etc/passwd

  1. 找出 root 有关的行
  1. Find lines related to root
1
grep "root" /etc/passwd
  1. 找出 root 用户的行
  1. Find the lines of the root user
1
grep "^root" /etc/passwd
  1. 匹配以 root 开头或者以 ub 开头的行
  1. Match lines starting with root or ub
1
grep -E "^(root|ub)" /etc/passwd

-E 选项:使用扩展正则表达式

  1. 匹配 root 用户和ubuntu用户的行

-E option: use extended regular expressions

  1. Match the lines of the root user and the ubuntu user
1
grep -E "^(root|ubuntu)\>" /etc/passwd

3 中会匹配 root1 root2 等开头的行,但是 4 不会。

  1. 过滤出 bin 开头的行并显示行号

In 3, lines starting with root1, root2, etc. will match, but in 4 they will not.

  1. Filter lines starting with bin and show line numbers
1
grep -n "^bin" /etc/passwd

-n : 显示行号

  1. 过滤出除了 root 开头的行

-n: show line numbers

  1. Filter out the lines starting with root
1
grep -v "^root" /etc/passwd

-v : 反转匹配

  1. 统计 root 用户出现的次数

-v: reverse matching

  1. Count the number of times the root user appears
1
grep -c '^root' /etc/passwd

-c : 统计次数

  1. 匹配 ubuntu 用户,最多两次

-c: count occurrences

  1. Match the ubuntu user, at most twice
1
grep -m 2 '^root' /etc/passwd

-m : 最多次数

  1. 匹配多文件列出存在信息的文件名字

-m: maximum count

  1. Match multiple files and list the names of the files containing the information
1
grep -l '^root' /etc/passwd pwd.txt null.txt

-l : 显示匹配成功的文件名字

  1. 显示不以 /bin/bash 结尾的行

-l: show the names of the files that matched successfully

  1. Show the lines that do not end with /bin/bash
1
grep -v "/bin/bash$" -n /etc/passwd
  1. 找出文件中的两位数或三位数
  1. Find two-digit or three-digit numbers in a file
1
grep -E "[0-9]{2,3}" /etc/passwd

上述写法不能获得正确的匹配结果,它会在超过 3 位数的数字中匹配其中的两位和三位。这是不符合题意的。如图所示。

image-20220504012821772

正确的写法应该进行左右封闭。

The above approach does not give a correct match: it matches two or three digits inside numbers with more than 3 digits. This does not satisfy the requirement, as shown in the figure.

image-20220504012821772

The correct way is to enclose the numbers on both sides.

1
grep -E "\<[0-9]{2,3}\>" /etc/passwd

image-20220504013029709

image-20220504013029709

在以下文本文件中查找。

Search in the following text file.

1
2
3
4
5
6
7
8
 I like my lover.
I love my lover.
He likes his lovers.
He loves his lovers.
#she loves her cat
i want ride my bike


  1. 找出以至少一个空格字符开头,后面是非空字符的行。
  1. Find lines that start with at least one space character followed by a non-space character.
1
grep -E "^[[:space:]]+[^[:space:]]" test.txt

第一个 ^ 表示行开头 第二个 [ ] 中的 ^ 表示取反

  1. 找出以 i 开头的行 忽略大小写

The first ^ means start of line; the second ^ inside [ ] means negation

  1. Find lines starting with i, ignoring case
1
2
3
grep -i "^i" test.txt
grep -E "^[iI]" test.txt
grep -E "^(i|I)" test.txt

-i : 忽略大小写

  1. 找出系统中root、 ubuntu 的用户信息

-i: ignore case

  1. Find the user information of root and ubuntu in the system
1
grep -E "^(root|ubuntu)\>" /etc/passwd
  1. 找出 /etc/init.d/functions 文件中的所有的函数名
  1. Find all the function names in the /etc/init.d/functions file
1
2
3
grep -E "^.+\(\)" /etc/init.d/functions
grep -E "[a-zA-Z]+\(\)" /etc/init.d/functions
grep -E "[[:alnum:]]+\(\)" /etc/init.d/functions
  1. 找出用户名和 shell 相同的用户
  1. Find the users whose username and shell are the same
1
grep -E  "^([^:]+\>).*\1$" /etc/passwd

思路:匹配非冒号的字符一次或多次,遇到冒号就右封闭,任意匹配中间结果,最后匹配 \1 ,\1 为前面小括号内的匹配结果,最后以 $ 结尾。

image-20220504015931745

Idea: match one or more non-colon characters, close on the right at a colon, match anything in the middle, and finally match \1, where \1 is the result matched by the earlier parentheses, ending with $.

image-20220504015931745

sed

首先在当前目录创建 pwd.txt

sed

First create pwd.txt in the current directory

  1. 替换文件的 root 为 change ,只替换一次和替换所有
  1. Replace root with change in the file, replacing only once and replacing all
1
2
3
4
5
6
# 替换一次
sed 's/root/change/' pwd.txt
# 模式中加个 p 表示打印替换的行 -n 取消默认输出 (-n 一般和 p 配合)
sed 's/root/change/p' pwd.txt -n
# 全局替换
sed 's/root/change/gp' pwd.txt -n
  1. 替换文件所有的 root 为 change,且仅仅打印替换的结果
  1. Replace all root with change in the file, and print only the replacement results
1
sed 's/root/change/gp' pwd.txt -n
  1. 替换前 10 行 b 开头的用户,改为 C,且仅仅打印替换的结果
  1. Replace users starting with b in the first 10 lines with C, and print only the replacement results
1
2
# 1,10 表示 1 到 10 行
sed -n '1,10s/^b/C/p' pwd.txt
  1. 替换前 10 行 b 开头的用户,改为 C,且将 m 开头的行改为 M,且仅仅显示替换的结果
  1. Replace users starting with b in the first 10 lines with C, and change lines starting with m to M, showing only the replacement results
1
2
# -e 编辑多次
sed -n -e '1,10s/^b/C/p' -e 's/^m/M/p' pwd.txt
  1. 删除 4 行后面的所有
  1. Delete everything after line 4
1
2
# d 删除 $ 结尾
sed '5,$d' pwd.txt
  1. 删除 root 开始 到 ftp 之间的行
  1. Delete the lines between root and ftp
1
2
# 双斜线中进行正则匹配
sed '/^root/,/^ftp/d' pwd.txt
  1. 将文件中空白字符开头的行,添加注释符#
  1. Add the comment symbol # to lines starting with whitespace characters
1
sed -e 's/^[[:space:]]/#/g' -e 's/^$/#/g' test.txt
  1. 删除文件的空白和注释行
  1. Delete the blank lines and comment lines from the file
1
2
sed -e '/^#/d' -e '/^$/d' test.txt
sed '/^#/d;/^$/d' test.txt
  1. 给文件的前三行添加@
  1. Add @ to the first three lines of the file
1
2
# -r 使用扩展正则
sed -r '1,3s/(^.)/@\1/' test.txt
  1. sed 取出 IP 地址
  1. Extract the IP address with sed
1
2
3
4
# 根据 ifconfig 的输出,先打印第二行,在将ip前面字符替换为空,再将ip 后面的字符替换为空
ifconfig | sed '2p' -n | sed 's/^.*inet//' | sed 's/netmask.*//'
ifconfig | sed '2s/^.*inet//;s/netmask.*//p' -n
ifconfig | sed -e '2s/^.*inet//' -e 's/netmask.*//p' -n
  1. 找出系统的版本
  1. Find out the system version
1
sed -r 's/^.*"(.*)"/\1/p' /etc/lsb-release -n 

-i 代表写入文件,不加-i都是修改内存中的数据

awk

-i means writing to the file; without -i, only the data in memory is modified

awk

  1. 在当前系统中打印出所有普通用户的用户名和家目录
  1. Print the usernames and home directories of all normal users in the current system
1
2
# -F 指定分隔符 NF 字段数量 $1 表示第一列 $0 表示一整行
awk -F ":" '$3 >= 1000{print $1,$(NF-1)}' /etc/passwd
  1. 给 test.txt 前五行添加#
  1. Add # to the first five lines of test.txt
1
2
# NR 行号 单引号中的双引号表示字符串
awk 'NR<6{print "#"$0}' test.txt
  1. 取出所有电话号码
  1. Extract all the phone numbers
1
2
3
4
5
6
7
8
9
10
11
12
# 文件内容: 姓名 地区 区号 电话号 捐款信息
Mike Dalian:[1235] 365-5426:123:456:789

Tom Dalian:[1235] 362-5426:123:456:789

Jerry Dalian:[1236] 154-5426:123:456:789

Moko Dalian:[1235] 999-5426:123:456:789

# -F 指定空格和:为分隔符
# ! 为取反 即非空行执行打印
awk -F "[ :]" '!/^$/{print $4}' aaa.txt
  1. 显示出 Tom 的电话
  1. Show Tom’s phone number
1
awk -F "[ :]" '/^Tom/{print $1,$4}' aaa.txt
  1. 找去地区为 D 开头的
  1. Find entries whose region starts with D
1
2
# ~ 为指定字段正则匹配
awk -F "[ :]" '$2~/^D/{print $2}' aaa.txt
  1. 显示区号是 1235 的人名
  1. Show the names of the people whose area code is 1235
1
awk -F "[ :]" '$3~/\[1235\]/{print $1}' aaa.txt
  1. 显示Mike 的捐款信息,并在每一条前加上$
  1. Show Mike’s donation information, prefixing each item with $
1
awk -F "[ :]" '/^Mike/{print "$"$(NF-2),"$"$(NF-1),"$"$(NF)}' aaa.txt
  1. 显示所有人的 地区+,+名字
  1. Show everyone’s region + , + name
1
2
3
awk -F "[ :]" '!/^$/{print $2","$1}' aaa.txt
# 通过 -v 修改输出间隔符
awk -F "[ :]" -v OFS="," '!/^$/{print $2,$1}' aaa.txt
  1. 删除文件的空白行
  1. Delete the blank lines from the file
1
2
3
awk '!/^$/' aaa.txt
# awk 默认动作为 {print $0}
awk '!/^$/{print $0}' aaa.txt