Featured image of post Shell基础

Shell基础

Linux Shell相关的一些东西。

目录

Shell基础

基础正则表达式符号

RE字符 意义 备注
^word 待查词word在行首
word$ 待查词word在行尾
. 一定有一个任意字符
* 重复零到无穷个 * 前面的字符
[ABC] ABC中的一个字符
[a-z] a~z中的一个字符
[^peach] 列出不包含peach中一个字符的行 反向选取
\{n,m\} 连续n~m个的前一个RE字符
\{n,\} 表示连续n个以上的前一个RE字符

grep管道命令

  • grep -n '[^a-z]pple' filename.md选取出pple前面不包含a~z中一个字符的行(像apple就不会被列出来)
  • grep -n '^$' filename.md列出文件中的所有空行
  • grep -v '^$' /etc/rsyslog.conf |grep -v '^#'去掉空行和以#开头的行

sed管道命令

格式:sed -[nefr] {操作}

  • sed '2,5d删除第2~5行
  • sed '2,$d删除第2行到最后一行
  • sed '2a add something'在第二行后加入add something
  • sed '2i add something'在第二行前加入add something
  • sed '2,5c Something将第二行到第五行按行替换为Something
  • sed 's/要被替换的字符/新的字符/g(部分替换)

栗子:

1
2
cat /etc/man_db.conf|grep "MAN"|sed 's/#.*$//g'|sed '/^$/d'
列出文件中含有MAN字符的整行并把以#开头的行换成空行之后删掉空行
  • sed -i xxx 修改原文件而不是仅修改打印,比较危险 例如sed -i 's/\.$/\!/g' filename.md表示修改filename.md中以.结尾的行的句末的.为!

awk

awk不是整行操作的,它更倾向于一行中分成数个字段来处理。

1
2
3
4
5
6
7
$ last -n 5
haoleng  tty1         :0               Thu Jun 18 07:28   still logged in
reboot   system boot  5.7.2-arch1-1    Thu Jun 18 07:27   still running
haoleng  tty1         :0               Wed Jun 17 16:07 - down   (00:41)
haoleng  tty1         :0               Wed Jun 17 16:04 - 16:07  (00:02)
reboot   system boot  5.7.2-arch1-1    Wed Jun 17 16:04 - 16:48  (00:44)
wtmp begins Sat Apr 11 12:49:36 2020

使用awk之后:

1
2
3
4
5
6
7
8
$ last -n 5 |awk '{print $1 "\t" $3}'
haoleng	:0
reboot	boot
haoleng	:0
haoleng	:0
reboot	boot
	
wtmp	Sat
awk的内置变量
变量名称 代表意义
NF 每一行($0)拥有的字段总数
NR 目前awk所处理的是第几行数据
FS 目前的分割字符
1
2
3
4
5
6
7
8
$ last -n 5|awk '{print $1 "\t line_count: "NF "\t line: " NR}'
haoleng	 line_count: 10	 line: 1
reboot	 line_count: 10	 line: 2
haoleng	 line_count: 10	 line: 3
haoleng	 line_count: 10	 line: 4
reboot	 line_count: 11	 line: 5
	 line_count: 0	 line: 6
wtmp	 line_count: 7	 line: 7

假设有一份薪资数据表pay.txt,内容如下

1
2
3
4
Name	1st	2nd	3th
John	23000	24000	25000
Wick	21000 	20000	26000
V	43000	42000	41900

可以用awk求和:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
$ cat pay.txt |\
> awk 'NR==1{printf "%10s %10s %10s %10s %10s\n",$1,$2,$3,$4,"Total"}
> NR>=2{total = $2 +$3 +$4;\
> printf "%10s %10s %10s %10s %10.2f\n",$1,$2,$3,$4,total}'
      Name        1st        2nd        3th      Total
      John      23000      24000      25000   72000.00
      Wick      21000      20000      26000   67000.00
         V      43000      42000      41900  126900.00
或者用下面的命令同样可以:
$ cat pay.txt |\
> awk '{if (NR==1) printf "%10s %10s %10s %10s %10s\n",$1,$2,$3,$4,"Total"}
> NR>=2{total = $2 +$3 +$4;\
> printf "%10s %10s %10s %10s %10.2f\n",$1,$2,$3,$4,total}'
      Name        1st        2nd        3th      Total
      John      23000      24000      25000   72000.00
      Wick      21000      20000      26000   67000.00
         V      43000      42000      41900  126900.00

简单的扩展正则表达式

RE字符 意义 范例
+ 一个或一个以上+前面的字符 egrep -n 'go+d' filename.md——good god…
? 一个或者零个?前面的字符 go+d与go?d的集合是 go*d
| 用or的方法找出数个字符串 `egrep -n ‘god
( ) 找出[组群]字符串 `egrep -n ‘g(lo
( )+ 重复的组群

一个简单的栗子:grep -v '^$' filename.md|grep -v '^#' 等价与 egrep -v '^$|^#' filename.md

Licensed under CC BY-NC-SA 4.0
最后更新于 2024-02-20 22:28 CST