正则
正则
正则就是一串有规律的字符串
grep
grep (global search regular expression(RE) and print out the line,全面搜索正则表达式并把行打印出来)是一种强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹配的行打印出来
Unix的grep家族包括grep、egrep和fgrep。egrep和fgrep的命令只跟grep有很小不同。egrep是grep的扩展,支持更多的re元字符, fgrep就是fixed grep或fast grep,它们把所有的字母都看作单词,也就是说,正则表达式中的元字符表示回其自身的字面意义,不再特殊。linux使用GNU版本的grep。它功能更强,可以通过-G、-E、-F命令行选项来使用egrep和fgrep的功能
grep选项
-
-a
: 不要忽略二进制数据 -
-An
:<显示列数>除了显示符合范本样式的那一行之外,并显示该行之后n行的内容 -
-Bn
: 在显示符合范本样式的那一行之外,并显示该行之前n行的内容。 -
-c
:统计符合范本样式的列数 -
-Cn
:<显示列数>或-<显示列数>除了显示符合范本样式的那一列之外,并显示该列之前后n行的内容 -
-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
: 只输出文件中匹配到的部分
grep 命令常见用法
语法:grep option 'word' filename
grep -c
:统计符合条件的行数
[root@zyxlinux01 grep]# grep "root" yx02.txt
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
[root@zyxlinux01 grep]# cat yx02.txt |grep -c "root"
2
[root@zyxlinux01 grep]# grep -c "root" yx02.txt
2
grep -n
:显示符合条件的行,并显示行号
[root@zyxlinux01 grep]# grep -n "root" yx02.txt
1:root:x:0:0:root:/root:/bin/bash
10:operator:x:11:0:operator:/root:/sbin/nologin
grep -i
:过滤时不区分大小写
[root@zyxlinux01 grep]# grep -i "root" yx02.txt
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/Root:/sbin/nologin
grep -v
:过滤时取反
[root@zyxlinux01 grep]# grep -v "nologin" yx02.txt
root:x:0:0:root:/root:/bin/bash
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
grep -A
:打印符合条件的行及其后面两行
[root@zyxlinux01 grep]# grep -nA2 "root" yx02.txt
4:root:x:0:0:root:/root:/bin/bash
5-kijnmhujhllllllllllllll:doofoie:fwf
6-bin:x:1:1:bin:/bin:/sbin/nologin
grep -B
:打印符合条件的行及其前面两行
[root@zyxlinux01 grep]# grep -nB2 "root" yx02.txt
2-shanglianghang
3-shangyihang
4:root:x:0:0:root:/root:/bin/bash
grep -C
:打印符合条件的行及其前后两行
[root@zyxlinux01 grep]# grep -nC2 "root" yx02.txt
2-shanglianghang
3-shangyihang
4:root:x:0:0:root:/root:/bin/bash
5-kijnmhujhllllllllllllll:doofoie:fwf
6-bin:x:1:1:bin:/bin:/sbin/nologin
grep '[0-9]'
:过滤带数字的行
[root@zyxlinux01 grep]# cat cx01.txt
diyihangnnne:eee:sdf:sdsdfS:dfdvr:
shanglianghang
shangyihang
root:x:0:0:root:/root:/bin/bash
kijnmhujhllllllllllllll:doofoie:fwf
[root@zyxlinux01 grep]# grep '[0-9]' cx01.txt
root:x:0:0:root:/root:/bin/bash
grep -v '[0-9]'
:过滤不带数字的行
[root@zyxlinux01 grep]# grep -v '[0-9]' cx01.txt
diyihangnnne:eee:sdf:sdsdfS:dfdvr:
shanglianghang
shangyihang
kijnmhujhllllllllllllll:doofoie:fwf
grep '^#'
:过滤以#
开头的行
[root@zyxlinux01 grep]# grep '^#' cx01.txt
# jljeoo
## lleidf343df90idfkp
grep '[^#]'
:^
在方括号内表示取反
[root@zyxlinux01 grep]# grep '^[^#]' cx01.txt
diyihangnnne:eee:sdf:sdsdfS:dfdvr:
shanglianghang
shangyihang
root:x:0:0:root:/root:/bin/bash
kijnmhujhllllllllllllll:doofoie:fwf
grep 'r.o'
:.
表示任意一个字符
[root@zyxlinux01 grep]# grep 'o.t' yx02.txt
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/Root:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
grep 'o*t'
: 过滤*
左边字符o重复0-n次的行
[root@zyxlinux01 grep]# grep 'o*y' yx02.txt
diyihangnnne:eee:sdf:sdsdfS:dfdvr:
shangyihang
sync:x:5:0:sync:/sbin:/bin/sync
nobody:x:99:99:Nobody:/:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
grep 'o\{2\}'
=grep -E 'o{2}'
=egrep 'o{2}'
:过滤有连续2个o的行
[root@zyxlinux01 grep]# grep 'o\{2\}' yx02.txt
root:x:0:0:root:/root:/bin/bash
kijnmhujhllllllllllllll:doofoie:fwf
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/Root:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
egrep 'o+'
:过滤 '+' 前字符o出现零次以上的行
[root@zyxlinux01 grep]# grep -E 'o+p' yx02.txt
operator:x:11:0:operator:/Root:/sbin/nologin
[root@zyxlinux01 grep]# grep -E 'o+s' yx02.txt
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
egrep 'o?'
:过滤 '?' 前字符o出现零次或一次的行
[root@zyxlinux01 grep]# egrep 'f?' cx01.txt
diyihangnnne:eee:sdf:sdsdfS:dfdvr:
shanglianghang
shangyihang
root:x:0:0:root:/root:/bin/bash
# jljeoo
kijnmhujhllllllllllllll:doofoie:fwf
## lleidf343df90idfkp
egrep 'a|b'
: 过滤有a或者b的行
[root@zyxlinux01 grep]# egrep 'm|g' cx01.txt
diyihangnnne:eee:sdf:sdsdfS:dfdvr:
shanglianghang
shangyihang
kijnmhujhllllllllllllll:doofoie:fwf
egrep '(ab){2}'
:过滤出现2次(ab)组合的行
[root@zyxlinux01 grep]# egrep '(ng){1}' cx01.txt
diyihangnnne:eee:sdf:sdsdfS:dfdvr:
shanglianghang
shangyihang
扩展
过滤/root/下所有txt文件中含有root的行
[root@zyxlinux01 grep]# grep -r --include="*.txt" 'root' /root/
/root/1.txt:root:x:0:0:root:/root:/bin/bash
/root/1.txt:operator:x:11:0:operator:/root:/sbin/nologin
/root/grep/nbaa.txt:root:x:0:0:root:/root:/bin/bash
/root/grep/nbaa.txt:operator:x:11:0:operator:/root:/sbin/nologin
/root/grep/nbab.txt:root:x:0:0:root:/root:/bin/bash
/root/grep/nbab.txt:operator:x:11:0:operator:/root:/sbin/nologin
/root/grep/yx02.txt:root:x:0:0:root:/root:/bin/bash
/root/grep/cx01.txt:root:x:0:0:root:/root:/bin/bash
sed
sed是一种流编辑器,它是文本处理中非常重要的工具,能够完美的配合正则表达式使用.
Sed主要用来自动编辑一个或多个文件;简化对文件的反复操作;编写转换程序等.
语法:
sed [options] 'command' file(s)
sed [options] -f scriptfile file(s)
sed 命令
a\ 在当前行下面插入文本
i\ 在当前行上面插入文本。
c\ 把选定的行改为新的文本。
d 删除,删除选择的行。
D 删除模板块的第一行。
s 替换指定字符
h 拷贝模板块的内容到内存中的缓冲区。
H 追加模板块的内容到内存中的缓冲区。
g 获得内存缓冲区的内容,并替代当前模板块中的文本。
G 获得内存缓冲区的内容,并追加到当前模板块文本的后面
l 列表不能打印字符的清单。
n 读取下一个输入行,用下一个命令处理新的行而不是用第一个命令。
N 追加下一个输入行到模板块后面并在二者间嵌入一个新行,改变当前行号码。
p 打印模板块的行。
P(大写) 打印模板块的第一行。
q 退出Sed。
b lable 分支到脚本中带有标记的地方,如果分支不存在则分支到脚本的末尾。
r file 从file中读行。
t label if分支,从最后一行开始,条件一旦满足或者T,t命令,将导致分支到带有标号的命令处,或者到脚本的末尾。
T label 错误分支,从最后一行开始,一旦发生错误或者T,t命令,将导致分支到带有标号的命令处,或者到脚本的末尾
w file 写并追加模板块到file末尾。
W file 写并追加模板块的第一行到file末尾。
! 表示后面的命令对所有没有被选定的行发生作用。
= 打印当前行号码。
# 把注释扩展到下一个换行符以前。
sed 替换标记
g 表示行内全面替换。
p 表示打印行。
w 表示把行写入一个文件。
x 表示互换模板块中的文本和缓冲区中的文本。
y 表示把一个字符翻译为另外的字符(但是不用于正则表达式)
\1 子串匹配标记
& 已匹配字符串标记
sed 元字符集
^ 匹配行开始,如:/^sed/匹配所有以sed开头的行
$ 匹配行结束,如:/sed$/匹配所有以sed结尾的行
. 匹配一个非换行符的任意字符,如:/s.d/匹配s后接一个任意字符,最后是d
* 匹配0个或多个字符,如:/*sed/匹配所有模板是一个或多个空格后紧跟sed的行。
[] 匹配一个指定范围内的字符,如/[ss]ed/匹配sed和Sed
[^] 匹配一个不在指定范围内的字符,如:/[^A-RT-Z]ed/匹配不包含A-R和T-Z的一个字母开头,紧跟ed的行。
\(..\) 匹配子串,保存匹配的字符,如s/\(love\)able/\1rs,loveable被替换成lovers
& 保存搜索字符用来替换其他字符,如s/love/**&**/,love这成**love**
\< 匹配单词的开始,如:/\<love/匹配包含以love开头的单词的行
\> 匹配单词的结束,如/love\>/匹配包含以love结尾的单词的行
x\{m\} 重复字符x,m次,如:/0\{5\}/匹配包含5个0的行
x\{m,\} 重复字符x,至少m次,如:/0\{5,\}/匹配至少有5个0的行
x\{m,n\} 重复字符x,至少m次,不多于n次,如:/0\{5,10\}/匹配5~10个0的行
sed 用法
- 匹配关键词
sed -n '/word/'p filename
[root@zyxlinux01 sed]# sed -n '/root/'p cx01.txt
root:x:0:0:root:/root:/bin/bash
[root@zyxlinux01 sed]# sed -n '/root/'Ip cx01.txt
root:x:0:0:root:/root:/bin/bash
Root:,,,eeyfiod:f223
I
: 不区分大小写
- 打印指定行
sed -n 'n'p filename
[root@zyxlinux01 sed]# sed -n '1'p cx01.txt
diyihangnnne:eee:sdf:sdsdfS:dfdvr:
[root@zyxlinux01 sed]# sed -n '1,4'p cx01.txt
diyihangnnne:eee:sdf:sdsdfS:dfdvr:
shanglianghang
shangyihang
root:x:0:0:root:/root:/bin/bash
`'6,$'`:打印第6至最后一行
`'1,$'`:打印全部
`'/^a/'`:打印以a开头的行
`'/r.o/'`:打印包含`r.o`的行(.表示任意一个字符)
`'oo*'`:打印包含oo*的行(*代表0-n个字符)
- 多点编辑,同时设置多个匹配
-e
[root@zyxlinux01 sed]# sed -e '2'p -e '/root/'p -n cx01.txt
shanglianghang
root:x:0:0:root:/root:/bin/bash
打印第2行和包含root的行
- 删除指定行
-d
(打印剩下的行,文件内容并没有改变;想要真正删除文件中指定的行需要加上-i
)
删除第3行
[root@zyxlinux01 sed]# sed '3d' cx01.txt
1 diyihangnnne:eee:sdf:sdsdfS:dfdvr:
2 shanglianghang
4 root:x:0:0:root:/root:/bin/bash
5 # jljeoo
6 kijnmhujhllllllllllllll:doofoie:fwf
7 ## lleidf343df90idfkp
8 Root:,,,eeyfiod:f223
删除5-7行
[root@zyxlinux01 sed]# sed '5,7d' cx01.txt
1 diyihangnnne:eee:sdf:sdsdfS:dfdvr:
2 shanglianghang
3 shangyihang
4 root:x:0:0:root:/root:/bin/bash
8 Root:,,,eeyfiod:f223
删除4到末尾所有行
[root@zyxlinux01 sed]# sed '4,$d' cx01.txt
1 diyihangnnne:eee:sdf:sdsdfS:dfdvr:
2 shanglianghang
3 shangyihang
'^$d': 删除空白行
'/^shang/'d:删除所有以shang开头的行
'$d':删除最后一行
删除包含 shang 的行
[root@zyxlinux01 sed]# sed '/shang/'d cx01.txt
1 diyihangnnne:eee:sdf:sdsdfS:dfdvr:
4 root:x:0:0:root:/root:/bin/bash
5 # jljeoo
6 kijnmhujhllllllllllllll:doofoie:fwf
7 ## lleidf343df90idfkp
8 Root:,,,eeyfiod:f223
sed替换
- 替换文件中的字符/字符串
[root@zyxlinux01 sed]# sed '1,4s/n/000/g' cx01.txt
1 diyiha000g000000000e:eee:sdf:sdsdfS:dfdvr:
2 sha000glia000gha000g
3 sha000gyiha000g
4 root:x:0:0:root:/root:/bi000/bash
5 # jljeoo
6 kijnmhujhllllllllllllll:doofoie:fwf
7 ## lleidf343df90idfkp
8 Root:,,,eeyfiod:f223
[root@zyxlinux01 sed]# sed -n '1,4s/n/000/gp' cx01.txt
1 diyiha000g000000000e:eee:sdf:sdsdfS:dfdvr:
2 sha000glia000gha000g
3 sha000gyiha000g
4 root:x:0:0:root:/root:/bi000/bash
1,4
:指定范围1-4行;s
: 表示替换;g
:全面替换标记
-n
选项和p
命令一起使用表示只打印那些发生替换的行
- 替换的同时进行文件的更改
[root@zyxlinux01 sed]# sed -i '1,4s/n/000/g' cx01.txt
[root@zyxlinux01 sed]# cat cx01.txt
1 diyiha000g000000000e:eee:sdf:sdsdfS:dfdvr:
2 sha000glia000gha000g
3 sha000gyiha000g
4 root:x:0:0:root:/root:/bi000/bash
5 # jljeoo
6 kijnmhujhllllllllllllll:doofoie:fwf
7 ## lleidf343df90idfkp
8 Root:,,,eeyfiod:f223
-i
:将会改变文件内容,在替换的同时将替换后内容写入文件
- 从第n处匹配开始替换, n 为数字
[root@zyxlinux01 sed]# echo lololololo |sed 's/lo/TT/4g'
lololoTTTT
[root@zyxlinux01 sed]# echo lololololo |sed 's/lo/TT/2g'
loTTTTTTTT
- 交换以
:
为分隔符的两段内容的位置
[root@zyxlinux01 sed]# head -n3 yx02.txt |sed -r 's/([^:]+):(.*):([^:]+)/\3:\2:\1/'
/bin/bash:x:0:0:root:/root:root
/sbin/nologin:x:1:1:bin:/bin:bin
/sbin/nologin:x:2:2:daemon:/sbin:daemon
前面小括号的组合,在后面我们用
\+
数字来表示
- 当替换的内容包含特殊符号时,就需要脱义符或者改变s后的区分符号
[root@zyxlinux01 sed]# head -n3 yx02.txt |sed -r 's@/sbin/nologin@xxx@g'
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:xxx
daemon:x:2:2:daemon:/sbin:xxx
- 不显示任何英文字母
[root@zyxlinux01 sed]# head -n3 yx02.txt |sed 's/[a-zA-Z]//g'
::0:0::/://
::1:1::/://
::2:2::/://
- 在所有行的前面加上固定的字符串
[root@zyxlinux01 sed]# head -n3 yx02.txt |sed -r 's/(.*)/Ha:\1/g'
Ha:root:x:0:0:root:/root:/bin/bash
Ha:bin:x:1:1:bin:/bin:/sbin/nologin
Ha:daemon:x:2:2:daemon:/sbin:/sbin/nologin
[root@zyxlinux01 sed]# head -n3 yx02.txt |sed -r 's/(.*)/Ha:&/g'
Ha:root:x:0:0:root:/root:/bin/bash
Ha:bin:x:1:1:bin:/bin:/sbin/nologin
Ha:daemon:x:2:2:daemon:/sbin:/sbin/nologin
前面小括号组合,后面可以用
\1
或者&
来表示
- 写入文件,将yx02中包含root的行写入a.txt
[root@zyxlinux01 sed]# touch a.txt
[root@zyxlinux01 sed]# sed -n '/root/w a.txt' yx02.txt
[root@zyxlinux01 sed]# cat a.txt
root:x:0:0:root:/root:/bin/bash
root:x:0:0:root:/root:/bin/bash
- 打印奇数行
'p;n'
,偶数行'n;p'
[root@zyxlinux01 sed]# sed -n 'p;n' cx01.txt
1 diyiha000g000000000e:eee:sdf:sdsdfS:dfdvr:
3 sha000gyiha000g
5 # jljeoo
7 ## lleidf343df90idfkp
[root@zyxlinux01 sed]# sed -n 'n;p' cx01.txt
2 sha000glia000gha000g
4 root:x:0:0:root:/root:/bi000/bash
6 kijnmhujhllllllllllllll:doofoie:fwf
8 Root:,,,eeyfiod:f223
awk
awk是一种编程语言,用于在linux/unix下对文本和数据进行处理。数据可以来自标准输入(stdin)、一个或多个文件,或其它命令的输出
awk支持用户自定义函数和动态正则表达式等先进功能,是linux/unix下的一个强大编程工具
awk在命令行中使用,但更多是作为脚本来使用
awk有很多内建的功能,比如数组、函数等,这是它和C语言的相同之处,灵活性是awk最大的优势
常用命令选项
-
-F
: 指定输入分隔符,可以是字符串或正则表达式(默认分隔符为空格或者空白字符) -
-v var=value
:赋值一个用户定义变量,将外部变量传递给awk -
-f scripfile
: 从脚本文件中读取awk命令
awk用法实例
- 打印文件所有行的第一段
[root@zyxlinux01 awk]# awk -F ':' '{print $1}' yx02.txt
root
adm
polkitd
avahi
avahi-autoipd
root
- 打印文件所有行
[root@zyxlinux01 awk]# awk -F ':' '{print $0}' yx02.txt
root:x:0:0:root:/root:/bin/bash
adm:x:3:4:adm:/var/adm:/sbin/nologin
polkitd:x:999:998:User for polkitd:/:/sbin/nologin
avahi:x:70:70:Avahi mDNS/DNS-SD Stack:/var/run/avahi-daemon:/sbin/nologin
avahi-autoipd:x:170:170:Avahi IPv4LL Stack:/var/lib/avahi-autoipd:/sbin/nologin
root:x:0:0:root:/root:/bin/bash
- 指定打印时的分隔符
[root@zyxlinux01 awk]# awk -F ':' '{OFS="%"} {print $1,$2,$5}' yx02.txt
root%x%/bin/bash
adm%x%adm
polkitd%x%User for polkitd
avahi%x%Avahi mDNS/DNS-SD Stack
avahi-autoipd%170%
root%x%root
- 匹配指定字符串的行
[root@zyxlinux01 awk]# awk '/nologin/' yx02.txt
adm:x:3:4:adm:/var/adm:/sbin/nologin
polkitd:x:999:998:User for polkitd:/:/sbin/nologin
avahi:x:70:70:Avahi mDNS/DNS-SD Stack:/var/run/avahi-daemon:/sbin/nologin
avahi-autoipd:170:170:/sbin/nologin
- 匹配某一段中的含有指定字符串的行
[root@zyxlinux01 awk]# awk -F ':' '$1 ~ /root/' yx02.txt
root:x:00root:/root:/bin/bash
root:x:0:0:root:/root:/bin/bash
[root@zyxlinux01 awk]# awk -F ':' '$0 ~ "/sbin/nologin"' yx02.txt
adm:x:3:4:adm:/var/adm:/sbin/nologin
polkitd:x:999:998:User for polkitd:/:/sbin/nologin
avahi:x:70:70:Avahi mDNS/DNS-SD Stack:/var/run/avahi-daemon:/sbin/nologin
avahi-autoipd:170:170:/sbin/nologin
- 支持正则
[root@zyxlinux01 awk]# awk -F ':' '$1 ~ /o+/' yx02.txt
root:x:00root:/root:/bin/bash
polkitd:x:999:998:User for polkitd:/:/sbin/nologin
avahi-autoipd:170:170:/sbin/nologin
root:x:0:0:root:/root:/bin/bash
- 同时支持多个表达式
[root@zyxlinux01 awk]# awk -F ':' '$1 ~ /o+/ {print $1,$3} /nologin/ {print $0}' yx02.txt
root 00root
adm:x:3:4:adm:/var/adm:/sbin/nologin
polkitd 999
polkitd:x:999:998:User for polkitd:/:/sbin/nologin
avahi:x:70:70:Avahi mDNS/DNS-SD Stack:/var/run/avahi-daemon:/sbin/nologin
avahi-autoipd 170
avahi-autoipd:170:170:/sbin/nologin
root 0
数学运算表达式
[root@zyxlinux01 awk]# awk -F ':' '$3==0' yx02.txt
root:x:0:0root:/root:/bin/bash
root:x:0:0:root:/root:/bin/bash
第三段等于0的行
[root@zyxlinux01 awk]# awk -F ':' '$3>=50' yx02.txt
polkitd:x:999:998:User for polkitd:/:/sbin/nologin
avahi:x:70:70:Avahi mDNS/DNS-SD Stack:/var/run/avahi-daemon:/sbin/nologin
avahi-autoipd:170:170:/sbin/nologin
第三段大于等于50的行
[root@zyxlinux01 awk]# awk -F ':' '$7!="/sbin/nologin" {print $0}' yx02.txt
root:x:0:0root:/root:/bin/bash
avahi-autoipd:170:170:/sbin/nologin
root:x:0:0:root:/root:/bin/bash
第七段不等于/sbin/nologin的行
[root@zyxlinux01 awk]# awk -F ':' '$3<$4' yx02.txt
root:x:0:0root:/root:/bin/bash
adm:x:3:4:adm:/var/adm:/sbin/nologin
第三段小于第四段的行
- 满足两个条件
[root@zyxlinux01 awk]# awk -F ':' '$3>"2" && $4<"50"' yx02.txt
adm:x:3:4:adm:/var/adm:/sbin/nologin
- 满足任意一个条件
[root@zyxlinux01 awk]# awk -F ':' '$3>"2" || $4<"50"' yx02.txt
root:x:0:0root:/root:/bin/bash
adm:x:3:4:adm:/var/adm:/sbin/nologin
polkitd:x:999:998:User for polkitd:/:/sbin/nologin
avahi:x:70:70:Avahi mDNS/DNS-SD Stack:/var/run/avahi-daemon:/sbin/nologin
avahi-autoipd:170:170:/sbin/nologin
root:x:0:0:root:/root:/bin/bash
[root@zyxlinux01 awk]# awk -F ':' '$3>"2" || $7 ~ /bash/' yx02.txt
adm:x:3:4:adm:/var/adm:/sbin/nologin
polkitd:x:999:998:User for polkitd:/:/sbin/nologin
avahi:x:70:70:Avahi mDNS/DNS-SD Stack:/var/run/avahi-daemon:/sbin/nologin
root:x:0:0:root:/root:/bin/bash
awk判断
- 如果第三段大于50,打印第一,第三,第七段
[root@zyxlinux01 awk]# awk -F ':' '{OFS="-"} {if ($3>50) {print $1,$3,$7}}' yx02.txt
polkitd-999-/sbin/nologin
avahi-70-/sbin/nologin
avahi-autoipd-170-
- 打印前五行
[root@zyxlinux01 awk]# awk -F ':' 'NR<=5' yx02.txt
root:x:0:0root:/root:/bin/bash
adm:x:3:4:adm:/var/adm:/sbin/nologin
polkitd:x:999:998:User for polkitd:/:/sbin/nologin
avahi:x:70:70:Avahi mDNS/DNS-SD Stack:/var/run/avahi-daemon:/sbin/nologin
avahi-autoipd:170:170:/sbin/nologin
- 打印前十行中第一段包含root或者sync的行
[root@zyxlinux01 awk]# awk -F ':' 'NR<=10 && $1 ~ /root|sync/' yx02.txt
root:x:0:0root:/root:/bin/bash
root:x:0:0:root:/root:/bin/bash
sync:x:5:0:sync:/sbin:/bin/sync
- 打印所有行,并打印行号
[root@zyxlinux01 awk]# awk -F ':' '{print NR"-"$0}' yx02.txt
1-root:x:0:0root:/root:/bin/bash
2-adm:x:3:4:adm:/var/adm:/sbin/nologin
3-polkitd:x:999:998:User for polkitd:/:/sbin/nologin
4-avahi:x:70:70:Avahi mDNS/DNS-SD Stack:/var/run/avahi-daemon:/sbin/nologin
5-avahi-autoipd:170:170:/sbin/nologin
6-root:x:0:0:root:/root:/bin/bash
7-sync:x:5:0:sync:/sbin:/bin/sync
- 打印所有行,并打印每一行有多少段
[root@zyxlinux01 awk]# awk -F ':' '{print NF"-"$0}' yx02.txt
6-root:x:0:0root:/root:/bin/bash
7-adm:x:3:4:adm:/var/adm:/sbin/nologin
7-polkitd:x:999:998:User for polkitd:/:/sbin/nologin
7-avahi:x:70:70:Avahi mDNS/DNS-SD Stack:/var/run/avahi-daemon:/sbin/nologin
4-avahi-autoipd:170:170:/sbin/nologin
7-root:x:0:0:root:/root:/bin/bash
7-sync:x:5:0:sync:/sbin:/bin/sync
- 赋值
[root@zyxlinux01 awk]# awk -F ':' '{OFS="-"} $1="root"' yx02.txt
root-x-0-0root-/root-/bin/bash
root-x-3-4-adm-/var/adm-/sbin/nologin
root-x-999-998-User for polkitd-/-/sbin/nologin
root-x-70-70-Avahi mDNS/DNS-SD Stack-/var/run/avahi-daemon-/sbin/nologin
root-170-170-/sbin/nologin
root-x-0-0-root-/root-/bin/bash
root-x-5-0-sync-/sbin-/bin/sync
将每一行第一段赋值为root
*求和
[root@zyxlinux01 awk]# awk -F ':' '{(tot=tot+$3)}; END {print tot}' yx02.txt
1247
[root@zyxlinux01 awk]# awk -F ':' '{(tot=tot+$3)}; END {print tot,$0}' yx02.txt
1247 sync:x:5:0:sync:/sbin:/bin/sync
awk -F ':' '{(tot=tot+$3)} {print tot}' yx02.txt
0
3
1002
1072
1242
1242
1247
[root@zyxlinux01 awk]# awk -F ':' '{(tot=tot+$3)} {print tot,$0}' yx02.txt
0 root:x:0:0root:/root:/bin/bash
3 adm:x:3:4:adm:/var/adm:/sbin/nologin
1002 polkitd:x:999:998:User for polkitd:/:/sbin/nologin
1072 avahi:x:70:70:Avahi mDNS/DNS-SD Stack:/var/run/avahi-daemon:/sbin/nologin
1242 avahi-autoipd:170:170:/sbin/nologin
1242 root:x:0:0:root:/root:/bin/bash
1247 sync:x:5:0:sync:/sbin:/bin/sync
tot
为和,默认为0;tot=tot+$3
表示每一次循环都会将第三段相加
正则扩展
sed 打印文件中特定的某行到某行之间的内容
[root@zyxlinux01 ~]# cat 1.txt
root:x
bin:x:1:1:bin:/bin:/sbin/nologin
[daemon]
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
[mail]
operator:x:11:0:operator:/root:/sbin/nologin
[root@zyxlinux01 ~]# sed -n '/\[daemon\]/,/\[mail\]/p' 1.txt
[daemon]
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
[mail]
sed 转换大小写字母
sed中,\u
表示大写, \|
表示小写
- 将每一行的首字母小写变成大写
[root@zyxlinux01 ~]# sed 's/\b[a-z]/\u&/g' 1.txt
Root:X
Bin:X:1:1:Bin:/Bin:/Sbin/Nologin
[Daemon]
Adm:X:3:4:Adm:/Var/Adm:/Sbin/Nologin
Lp:X:4:7:Lp:/Var/Spool/Lpd:/Sbin/Nologin
Sync:X:5:0:Sync:/Sbin:/Bin/Sync
Shutdown:X:6:0:Shutdown:/Sbin:/Sbin/Shutdown
Halt:X:7:0:Halt:/Sbin:/Sbin/Halt
[Mail]
Operator:X:11:0:Operator:/Root:/Sbin/Nologin
[root@zyxlinux01 ~]# sed 's/\b[a-z]/\|&/g' 1.txt
|root:|x
|bin:|x:1:1:|bin:/|bin:/|sbin/|nologin
[|daemon]
|adm:|x:3:4:|adm:/|var/|adm:/|sbin/|nologin
|lp:|x:4:7:|lp:/|var/|spool/|lpd:/|sbin/|nologin
|sync:|x:5:0:|sync:/|sbin:/|bin/|sync
|shutdown:|x:6:0:|shutdown:/|sbin:/|sbin/|shutdown
|halt:|x:7:0:|halt:/|sbin:/|sbin/|halt
[|mail]
|operator:|x:11:0:|operator:/|root:/|sbin/|nologin
- 把所有小写变成大写,大写变成小写
[root@zyxlinux01 ~]# sed 's/[a-z]/\u&/g' 1.txt
ROOT:X
BIN:X:1:1:BIN:/BIN:/SBIN/NOLOGIN
[DAEMON]
ADM:X:3:4:ADM:/VAR/ADM:/SBIN/NOLOGIN
LP:X:4:7:LP:/VAR/SPOOL/LPD:/SBIN/NOLOGIN
SYNC:X:5:0:SYNC:/SBIN:/BIN/SYNC
SHUTDOWN:X:6:0:SHUTDOWN:/SBIN:/SBIN/SHUTDOWN
HALT:X:7:0:HALT:/SBIN:/SBIN/HALT
[MAIL]
OPERATOR:X:11:0:OPERATOR:/ROOT:/SBIN/NOLOGIN
[root@zyxlinux01 ~]# sed -e 's/[A-Z]/\|&/g' 1.txt
root:x
bin:x:1:1:bin:/bin:/sbin/nologin
[daemon]
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
[mail]
operator:x:11:0:operator:/root:/sbin/nologin
sed 在文件制定的行最后添加一个数字
[root@zyxlinux01 ~]# sed 's/\(^s.*\)/\1 "-->" 9527/' 1.txt
root:x
bin:x:1:1:bin:/bin:/sbin/nologin
[daemon]
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync "-->" 9527
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown "-->" 9527
halt:x:7:0:halt:/sbin:/sbin/halt
[mail]
operator:x:11:0:operator:/root:/sbin/nologin
也可以用
sed 's/\(^s.*\)/& "-->" 9527/' 1.txt
sed 删除包含指定关键字的下一行到最后一行
[root@zyxlinux01 ~]# sed '/bin/{p;:a;N;$!ba;d}' 1.txt
root:x
bin:x:1:1:bin:/bin:/sbin/nologin
p;
: 不加的话会删除包含关键字的行
:a
: 定义的标签,不加会报错提示sed: 无法为目的为“a”的跳转找到标签
N;
: 表示将下一行添加到模式空间,匹配到最后一行时才退出标签循环
d
: 删除,将这个模式空间的全部内容清除
打印1到10行包含某个字符串的行
[root@zyxlinux01 ~]# sed -n '1,10{/\/sbin\/nologin/p}' 1.txt
bin:x:1:1:bin:/bin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
[root@zyxlinux01 ~]# sed -n '1,10p' 1.txt |sed -n '/\/sbin\/nologin/p'
bin:x:1:1:bin:/bin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
[root@zyxlinux01 ~]# sed -n '1,10p' 1.txt |grep '/sbin/nologin'
bin:x:1:1:bin:/bin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
awk 中使用外部shell变量
[root@zyxlinux01 awk]# vim yhwbbl.sh
#!/bin/bash
A=27
awk -v a=$A -F ':' '{print a ":" $2}' 1.txt
-v
:间接引用.如上,A的值为27,但是我们只想用27这个值,却不想用A这个变量,于是把A赋值给另一个变量a(a=$A),然后在awk中引用,就可以使用27这个值.打印a和每一行第二段,中间使用分隔符‘:’。
[root@zyxlinux01 awk]# cat 1.txt
1111:bin:x:1:1:bin:/bin:/sbin/nologin
2222:daemon]
1111:adm:x:3:4:adm:/var/adm:/sbin/nologin
3333:lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
2222:sync:x:5:0:sync:/sbin:/bin/sync
1111:shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
3333:halt:x:7:0:halt:/sbin:/sbin/halt
2222:operator:x:11:0:operator:/root:/sbin/nologin
[root@zyxlinux01 awk]# bash yhwbbl.sh
27:bin
27:daemon]
27:adm
27:lp
27:sync
27:shutdown
27:halt
27:operator
- 编辑脚本
[root@zyxlinux01 awk]# vim wb.sh
#! /bin/bash awk中使用外部变量
sort -n 1.txt |awk -F ":" '{print $1}' |uniq >id.txt
for id in `cat id.txt`; do
echo "[$id]"
awk -v id2=$id -F ":" '$1==id2{print $2}' 1.txt
done
将1.txt进行排序打印第一段去重之后输入重定向到id.txt
cat id.txt
查看id.txt
echo "[$id]"
先打印每一行并加上[ ]
-v id2=$id
重新赋值$id为id2
- 执行结果
[root@zyxlinux01 awk]# bash wb.sh
[1111]
bin
adm
shutdown
[2222]
daemon]
sync
operator
[3333]
lp
halt
- 其他写法
#! /bin/bash awk中使用外部变量
sort -n 1.txt |awk -F ":" '{print $1}' |uniq >id.txt
for id in `cat id.txt`; do
echo "[$id]"
awk -v id2=$id -F ":" '$1==id2{print $1 "-" $2}' 1.txt
done
[root@zyxlinux01 awk]# sh wb.sh
[1111]
1111-bin
1111-adm
1111-shutdown
[2222]
2222-daemon]
2222-sync
2222-operator
[3333]
3333-lp
3333-halt
awk合并文件
将两个文件中第一列相同的行合并到同一行中
[root@zyxlinux01 awk]# cat a.txt
1 aa
2 bb
3 cc
4 dd
[root@zyxlinux01 awk]# cat b.txt
1 jj
2 kk
3 ll
4 tt
5 ee
[root@zyxlinux01 awk]# awk 'NR==FNR{a[$1]=$2}NR>FNR{print $0,a[$1]}' a.txt b.txt
1 jj aa
2 kk bb
3 ll cc
4 tt dd
5 ee
[root@zyxlinux01 awk]# awk 'NR==FNR{a[$1]=$2}NR>FNR{print $0,a[$1]}' b.txt a.txt
1 aa jj
2 bb kk
3 cc ll
4 dd tt
[root@zyxlinux01 awk]# awk 'NR==FNR{a[$1]=$2}NR>FNR{print a[$1],$0}' a.txt b.txt
aa 1 jj
bb 2 kk
cc 3 ll
dd 4 tt
5 ee
[root@zyxlinux01 awk]# awk 'NR==FNR{a[$1]=$2}NR>FNR{print a[$1],$0}' b.txt a.txt
jj 1 aa
kk 2 bb
ll 3 cc
tt 4 dd
[root@zyxlinux01 awk]# awk 'NR==FNR{a[$1]=$0}NR>FNR{print $0,a[$1]}' a.txt b.txt
1 jj 1 aa
2 kk 2 bb
3 ll 3 cc
4 tt 4 dd
5 ee
[root@zyxlinux01 awk]# awk 'NR==FNR{a[$1]=$0}NR>FNR{print $0,a[$1]}' b.txt a.txt
1 aa 1 jj
2 bb 2 kk
3 cc 3 ll
4 dd 4 tt
NR表示所有的行数,FNR表示正在读取的行数(都是从零开始计数,NR不清零,FNR读完一个文件后清零)
NR==FNR表示读取第一个文件的时候,NR>FNR表示读取第二个文件的时候
数组a相当于一个map
第二个文件有多少行就打印多少行,以为只有读取第二个文件时才满足NR>FNR,才会打印
awk 将一个文件多行连接成一行
[root@zyxlinux01 awk]# cat lj.txt
10
233
456
4674
3434
35
[root@zyxlinux01 awk]# awk '{printf("%s ",$0)}' lj.txt; echo ""
10 233 456 4674 3434 35
%s
后面要跟空格,不然所有字符串会直接连在一起
[root@zyxlinux01 awk]# awk '{printf("%s+",$0)}' lj.txt; echo ""
10+233+456+4674+3434+35+
%s
后面也可以跟 + ,最后一个也是带“+”的;echo ""
的作用是换行
[root@zyxlinux01 awk]# cat lj.txt |xargs|sed 's/ /+/g'
10+233+456+4674+3434+35
使用
cat lj.txt |xargs
也可以实现
[root@zyxlinux01 awk]# paste -s lj.txt
10 233 456 4674 3434 35
[root@zyxlinux01 awk]# paste -s -d "+" lj.txt
10+233+456+4674+3434+35
另外
paste -s
也能实现
awk中gsub函数的使用
- 将文件yx02.txt中所有
login
替换成AAA
[root@zyxlinux01 awk]# cat yx02.txt
root:x:0:0root:/root:/bin/bash
adm:x:3:4:adm:/var/adm:/sbin/nologin
polkitd:x:999:998:User for polkitd:/:/sbin/nologin
avahi:x:70:70:Avahi mDNS/DNS-SD Stack:/var/run/avahi-daemon:/sbin/nologin
avahi-autoipd:170:170:/sbin/nologin
root:x:0:0:root:/root:/bin/bash
sync:x:5:0:sync:/sbin:/bin/sync
[root@zyxlinux01 awk]# awk 'gsub(/login/,"AAA")' yx02.txt
adm:x:3:4:adm:/var/adm:/sbin/noAAA
polkitd:x:999:998:User for polkitd:/:/sbin/noAAA
avahi:x:70:70:Avahi mDNS/DNS-SD Stack:/var/run/avahi-daemon:/sbin/noAAA
avahi-autoipd:170:170:/sbin/noAAA
- 替换$7中的
nologin
为AAA
[root@zyxlinux01 awk]# awk -F ":" 'gsub(/login/,"AAA",$7) {print $7}' yx02.txt
/sbin/noAAA
/sbin/noAAA
/sbin/noAAA
[root@zyxlinux01 awk]# awk -F ":" 'gsub(/login/,"AAA",$7) {print $0}' yx02.txt
adm x 3 4 adm /var/adm /sbin/noAAA
polkitd x 999 998 User for polkitd / /sbin/noAAA
avahi x 70 70 Avahi mDNS/DNS-SD Stack /var/run/avahi-daemon /sbin/noAAA
awk 截取指定多个域为一行
for j in `seq 0 20`; do
let x=100*$j
let y=$x+1
let z=$x+100
for i in `seq $y $z` ; do
awk -v a=$i '{printf $a " "}' example.txt >>/tmp/test.txt
echo " " >>/tmp/test.txt
done
done
#!/bin/bash
for i in `seq 1 20` ; do
awk -F ':' -v a=$i '{printf $a " "}' /etc/passwd >>/home/test/1.txt
echo " " >>/home/test/1.txt
done
grep 或 egrep 或awk 过滤两个或多个关键词
[root@zyxlinux01 awk]# grep -E 'root|sync' yx02.txt
root:x:0:0root:/root:/bin/bash
root:x:0:0:root:/root:/bin/bash
sync:x:5:0:sync:/sbin:/bin/sync
[root@zyxlinux01 awk]# egrep 'root|sync' yx02.txt
root:x:0:0root:/root:/bin/bash
root:x:0:0:root:/root:/bin/bash
sync:x:5:0:sync:/sbin:/bin/sync
[root@zyxlinux01 awk]# awk '/root|sync/' yx02.txt
root:x:0:0root:/root:/bin/bash
root:x:0:0:root:/root:/bin/bash
sync:x:5:0:sync:/sbin:/bin/sync
awk编写生成以下结构文件的程序
awk编写生成以下结构文件的程序。( 最后列使用现在的时间,时间格式为YYYYMMDDHHMISS) 各列的值应如下所示,每增加一行便加1,共500万行
1,1,0000000001,0000000001,0000000001,0000000001,0000000001,0000000001,2005100110101
2,2,0000000002,0000000002,0000000002,0000000002,0000000002,0000000002,2005100110101
#! /bin/bash
for i in `seq 1 5000000`; do
n=`echo "$i"|awk '{print length($0)}'`
export m=$[10-$n]
export o=`perl -e '$a='0'; $b=$a x $ENV{"m"}; print $b;'`
export j=$i
p=`perl -e '$c=$ENV{"o"}.$ENV{"j"}; print $c;'`
echo "$i,$i,$p,$p,$p,$p,$p,$p,`date +%Y%m%d%H%M%S`"
done
awk用print打印单引号
[root@zyxlinux01 awk]# awk '{print "This is a '"$"'"$1}' 1.txt
This is a $1111:bin:x:1:1:bin:/bin:/sbin/nologin
This is a $2222:daemon]
This is a $1111:adm:x:3:4:adm:/var/adm:/sbin/nologin
This is a $3333:lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
This is a $2222:sync:x:5:0:sync:/sbin:/bin/sync
This is a $1111:shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
This is a $3333:halt:x:7:0:halt:/sbin:/sbin/halt
This is a $2222:operator:x:11:0:operator:/root:/sbin/nologin
[root@zyxlinux01 awk]# awk '{print "This is a '"'"'"$1}' 1.txt
This is a '1111:bin:x:1:1:bin:/bin:/sbin/nologin
This is a '2222:daemon]
This is a '1111:adm:x:3:4:adm:/var/adm:/sbin/nologin
This is a '3333:lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
This is a '2222:sync:x:5:0:sync:/sbin:/bin/sync
This is a '1111:shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
This is a '3333:halt:x:7:0:halt:/sbin:/sbin/halt
This is a '2222:operator:x:11:0:operator:/root:/sbin/nologin
[root@zyxlinux01 awk]# awk '{print "This is a '"^^"'"$1}' 1.txt
This is a ^^1111:bin:x:1:1:bin:/bin:/sbin/nologin
This is a ^^2222:daemon]
This is a ^^1111:adm:x:3:4:adm:/var/adm:/sbin/nologin
This is a ^^3333:lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
This is a ^^2222:sync:x:5:0:sync:/sbin:/bin/sync
This is a ^^1111:shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
This is a ^^3333:halt:x:7:0:halt:/sbin:/sbin/halt
This is a ^^2222:operator:x:11:0:operator:/root:/sbin/nologin
在awk中使用脱义字符\是起不到作用的,如果想打印特殊字符,只能使用'""' 这样的组合才可以.
这里自左至右为单引号 双引号 双引号 单引号其中两个单引号为一对,两个双引号为一对。想脱义$那就是'"$"' 脱义单引号那就是 '"'"'.
把两个文件中相同的行合并成一行
[root@zyxlinux01 awk]# cat a.txt
1 aa
2 bb
3 cc
4 dd
[root@zyxlinux01 awk]# cat b.txt
1 jj
2 kk
3 ll
4 tt
5 ee
[root@zyxlinux01 awk]# paste -d '&' a.txt b.txt
1 aa&1 jj
2 bb&2 kk
3 cc&3 ll
4 dd&4 tt
&5 ee
[root@zyxlinux01 awk]# paste -d '+' a.txt b.txt
1 aa+1 jj
2 bb+2 kk
3 cc+3 ll
4 dd+4 tt
+5 ee
-d
指定两个文件连接处的连接字符
[root@zyxlinux01 awk]# awk 'NR==FNR {a[FNR]=$0} NR>FNR {print a[FNR],"&",$0}' a.txt b.txt
1 aa & 1 jj
2 bb & 2 kk
3 cc & 3 ll
4 dd & 4 tt
& 5 ee
[root@zyxlinux01 awk]# awk 'NR==FNR {a[FNR]=$0} NR>FNR {print a[FNR],"$",$0}' a.txt b.txt
1 aa $ 1 jj
2 bb $ 2 kk
3 cc $ 3 ll
4 dd $ 4 tt
$ 5 ee
[root@zyxlinux01 awk]# awk 'NR==FNR {a[FNR]=$0} NR>FNR {print a[FNR],"'"'"'",$0}' a.txt b.txt
1 aa ' 1 jj
2 bb ' 2 kk
3 cc ' 3 ll
4 dd ' 4 tt
' 5 ee