linux shell脚本攻略 第二章 命令之乐 cat,find,tr,sort,uniq,split等

目录

1. 使用cat进行拼接

2.录制并回放终端会话

3.find命令

4. xargs命令

5. tr命令进行转换

6.校验和与核实(md5)

7.加密工具与散列

8.排序,唯一与重复

9.临时文件命名

10.分割文件和数据

11.根据扩展名切分文件名

12.批量重命名和移动

13.交互输入自动化

14.使用并行进程加速命令执行


 

介绍常用命令grep,sed,find等命令。

1. 使用cat进行拼接

cat本身表示拼接(concatnate)。

  • 将标准输入与文件内容拼接
Ian>ls |cat  - out.txt 
func.sh
out.txt
prp.sh
script.sh
     1	func.sh
     2	out.txt
     3	script.sh
  • 摆脱多余的空白行:cat -s

可将多行空白行压缩成一行

Ian>cat space.txt 
l1


l2
l3



l4
Ian>cat -s space.txt 
l1

l2
l3

l4
  • 将制表符显示成^I:cat -T file
  • 显示行号:cat -n
  • 所有参数:

-n 或 --number:由 1 开始对所有输出的行数编号。

-b 或 --number-nonblank:和 -n 相似,只不过对于空白行不编号。

-s 或 --squeeze-blank:当遇到有连续两行以上的空白行,就代换为一行的空白行。

-v 或 --show-nonprinting:使用 ^ 和 M- 符号,除了 LFD 和 TAB 之外。

-E 或 --show-ends : 在每行结束处显示 $。

-T 或 --show-tabs: 将 TAB 字符显示为 ^I。

-A, --show-all:等价于 -vET。

-e:等价于"-vE"选项;

-t:等价于"-vT"选项;

2.录制并回放终端会话

使用script和scriptplay命令

  • 录制:script -t 2> timing.log -a output.session  使用exit结束
  • 回放:scriptreplay timing.log output.session 自动回放录制的命令
Ian>script -t 2> timing.log -a output.session
Script started, file is output.session
Ian>ls
func.sh         out.txt  script.sh  tab.py
output.session  prp.sh   space.txt  timing.log
Ian>history |grep ll
    6  ll
    8  ll
   10  ll
   11  echo hello !
   15  ll
   18  ll
   21  ll
   25  ll
   27  ll
   29  ll
   30  sudo ./vmware-install.pl 
   78  sudo apt install vim  
   98  ll && PATH="/home/ian/Documents/:$PATH"
  135  ll
  175  ll
  207  history |grep ll
Ian>exit
exit
Script done, file is output.session
Ian>scriptreplay timing.log output.session 
Ian>ls
func.sh         out.txt  script.sh  tab.py
output.session  prp.sh   space.txt  timing.log
Ian>history |grep ll
    6  ll
    8  ll
   10  ll
   11  echo hello !
   15  ll
   18  ll
   21  ll
   25  ll
   27  ll
   29  ll
   30  sudo ./vmware-install.pl 
   78  sudo apt install vim  
   98  ll && PATH="/home/ian/Documents/:$PATH"
  135  ll
  175  ll
  207  history |grep ll
Ian>exit
exit

3.find命令

  • 列出当前目录下所有的文件和文件夹

find .

find . -print0

-print用于确认分隔符,默认'\n',如果使用print0,则用'\0'作为分隔符

Ian>find . -print
.
./tab.py
./out.txt
./timing.log
./space.txt
./script.sh
./func.sh
./prp.sh
./output.session
Ian>find . -print0
../tab.py./out.txt./timing.log./space.txt./script.sh./func.sh./prp.sh./output.session
  • 根据文件名或者正则搜索

find path -name

find path -iname:忽略大小写

find path \( -name "*.txt" -o -name "*.pdf" \):匹配多个条件

find path -path "*/ian/*":匹配整个路径

find . ! -name "*.txt*":找出不包含txt的文件

Ian>ls
func.sh  output.session  out.txt  prp.sh  script.sh  space.txt  tab.py  timing.log
Ian>find . -name "*out*"
./out.txt
./output.session
Ian>find . -name "*Out*"

Ian>find . -iname "*Out*"
./out.txt
./output.session
Ian>find . \( -name "*txt*" -o -name "*sh*" \)
./out.txt
./space.txt
./script.sh
./func.sh
./prp.sh
Ian>mkdir f1
Ian>touch f1/a.log
Ian>find . -path "*/f1/*"
./f1/a.log
Ian>find . ! -name "*.txt"
.
./f1
./f1/a.log
./f1/b.log
./tab.py
./timing.log
./script.sh
./func.sh
./prp.sh
./output.session


  • 根据深度查找

find . -maxdepth 1:最深路径,1为当前路径

find . -mindepth 2:最浅路径,从这个深度开始查找,忽略比这个深度浅的

Ian>ls
f1  func.sh  output.session  out.txt  prp.sh  script.sh  space.txt  tab.py  timing.log
Ian>touch dep.txt
Ian>touch f1/dep.txt
Ian>find . -maxdepth 1 -name "*dep*"
./dep.txt
Ian>find . -mindepth 2 -name "*dep*"
./f1/dep.txt
  • 按照文件类型匹配

find . -type d:只查出目录

类型参数:普通文件f  文件夹文件d  符号文件l  字符设备c  块设备b

  • 按照文件时间匹配

-atime:访问时间,天为单位

-mtime:内容修改时间,天为单位

-ctime:权限或者所有权最后一次改变的时间,天为单位

其中+2代表2天之外,-3代表3天之内

amin,mmin,cmim分别是分钟为单位的访问,内容修改,权限改变时间

Ian>find . -mmin +800
./out.txt
./script.sh
./func.sh
./prp.sh
Ian>find . -atime -2
.
./f1
./f1/a.log
./f1/dep.txt
./f1/b.log
./tab.py
./out.txt
./timing.log
./space.txt
./script.sh
./func.sh
./dep.txt
./prp.sh
./output.session

-newer:找出比一个文件更新(修改时间更近的文件)

Ian>find . -newer dep.txt -type f
./f1/dep.txt
  • 按照文件大小匹配

find . -size +2k:找出大于2k的文件

  • 删除匹配的文件:-delete

find . -name "*.txt" -delete:删除所有txt文件

  • 按照文件权限和所有权匹配

-perm 644:按照权限匹配

-user ian:按照用户匹配

  • find后执行命令或者动作

使用exec可以在find之后执行命令

find . -name "*.sh" -exec cat {} \; > all_txt.txt

这个命令将所有.sh的文件拼接到一个文件中。其中每个找到的文件都被{}代替,所以需要分号";"来分割每个命令

跳过特定目录

  • 使用prune命令(不好用)
Ian>find . \( -path ./f1 -prune \) -o \( -type f \)
./f1
./tab.py
./out.txt
./timing.log
./space.txt
./all_txt.txt
./script.sh
./func.sh
./dep.txt
./prp.sh

4. xargs命令

接收数据流命令。可以将数据重新格式化。

  • 格式化数据

多行转单行,单行转多行:

-n表示一行的元素个数,然后划分为多行

Ian>cat xars.txt 
1 2 3
4 5 6
7
Ian>cat xars.txt |xargs 
1 2 3 4 5 6 7
Ian>cat xars.txt |xargs -n 4
1 2 3 4
5 6 7
  • 自定义分隔符:-d
Ian>echo "12v34v56v78"|xargs -d v
12 34 56 78
  • 给脚本传参

echo "12v34v56v78"|xargs -n 1 -d v ./do.sh:每次向脚本传一个字符串,执行多次脚本

echo "12v34v56v78"|xargs -n 1 -d v -I {} ./do.sh -p {} -h:脚本有多个参数传递时,仅替换传入的参数。{}为循环执行

  • 和find搭配使用

find . -name "*.txt" -type f -print0|xargs -0 rm -f :删除所有txt文件

find source_path -name "*.c" -type f -print0|xargs -0 wc -l:统计c语言的代码行数

5. tr命令进行转换

tr命令介绍:https://www.jb51.net/article/103892.htm

  • 转换字符:
Ian>echo "Hello World!" | tr 'A-Z' 'a-z' 
hello world!
Ian>cat sum.txt | echo $[ $(tr "\n" "+") 0]
15

可以使用字符类转换: 

Ian>echo "123he4l4lo6" | tr '[:lower:]' '[:upper:]'
123HE4L4LO6

字符类包括:

\NNN 八进制值的字符 NNN (1 to 3 为八进制值的字符)

\\ 反斜杠

\a Ctrl-G 铃声

\b Ctrl-H 退格符

\f Ctrl-L 走行换页

\n Ctrl-J 新行

\r Ctrl-M 回车

\t Ctrl-I tab键

\v Ctrl-X 水平制表符

CHAR1-CHAR2 从CHAR1 到 CHAR2的所有字符按照ASCII字符的顺序

[CHAR*] in SET2, copies of CHAR until length of SET1

[CHAR*REPEAT] REPEAT copies of CHAR, REPEAT octal if starting with 0

[:alnum:] 所有的字母和数字

[:alpha:] 所有字母

[:blank:] 水平制表符,空白等

[:cntrl:] 所有控制字符

[:digit:] 所有的数字

[:graph:] 所有可打印字符,不包括空格

[:lower:] 所有的小写字符

[:print:] 所有可打印字符,包括空格

[:punct:] 所有的标点字符

[:space:] 所有的横向或纵向的空白

[:upper:] 所有大写字母

 

  • 删除字符:tr -d
Ian>echo "123he4l4lo6" | tr -d "0-9"
hello
  • 字符补集:tr -c
Ian>echo "123he4l4lo6" | tr -d -c "0-9"
123446

上面可以将不在补集中的字符都删掉

  • 压缩字符:tr -s
Ian>echo "shell      is     good script"|tr -s " "
shell is good script

6.校验和与核实(md5)

用于文件完整性测试的特定密钥就是校验和。

  • 生成md5:
Ian>md5sum all_txt.txt 
5c8b5885df01c5cf0b0eeb2b628579df  all_txt.txt
  • 校验md5:
Ian>md5sum all_txt.txt > all_txt.md5
Ian>md5sum -c all_txt.md5 
all_txt.txt: OK

sha-1也是常用的校验算法,用法与md5相同,把md5sum改为sha1sum即可

  • 校验目录
Ian>md5deep -rl f1/
d41d8cd98f00b204e9800998ecf8427e  f1/a.log
d41d8cd98f00b204e9800998ecf8427e  f1/b.log
d41d8cd98f00b204e9800998ecf8427e  f1/dep.txt

7.加密工具与散列

用于防止数据遭未经授权的访问。

  • crypt

crypt PASSWORD <input_file >output_file:加密

crypt PASSWORD -d <encrypted_file >output_file:解密

  • gpg

gpg -c file:加密

gpg file.gpg:解密

  • base64

base64 filename > output_file:加密

base64 -d file > output_file:解密

8.排序,唯一与重复

排序:sort

详细:https://www.cnblogs.com/delav/p/9956819.html

唯一:uniq,要求文件必须是排序好的

  • sort基本用法

对多个文件排序:sort f1 f2 > sort.txt,默认是首字母排序

按照数字顺序排序:sort -n f1

逆序排序:sort -r

按照月份排序:sort -M

合并两个排序过的文件:sort -m f1 f2

找出已排序文件中不同的行:sort f1 f2|uniq

检查是否排序过:sort -C f; if [ $? -eq 0]; then echo 1; else echo 0;fi

  • sort常用方法

按照键值列排序:sort -k 2,按照第二列排序

按照键值列排序,切指定列的范围:sort -k 2,3 f,按照列的2-3个字符来排序

忽略空格仅考虑数字字母作为键值:sort -bd f。其中-b为忽略空格,-d为只奥绿空格和字母数字

生成\0作为分隔符的文件用于和xargs一起使用:sort -z

  • uniq用法

通过消除重复内容,用于找出唯一的行,也可以找出重复行

显示唯一的行:sort f1 | uniq

统计各行出现的次数:sort f1 |uniq -c找出重复行:sort f1 |uniq -d

Ian>sort xars.txt wargs.txt > sort.txt
Ian>cat sort.txt 
1
1 2 3
2
2
3
4
4 5 6
7
Ian>sort xars.txt wargs.txt|uniq
1
1 2 3
2
3
4
4 5 6
7
Ian>sort xars.txt wargs.txt|uniq -c
      1 1
      1 1 2 3
      2 2
      1 3
      1 4
      1 4 5 6
      1 7
Ian>sort xars.txt wargs.txt|uniq -d
2

忽略前n个字符:sort -s

指定键值的最大字符数:sort -w

Ian>cat data.txt 
u:01:gnu
d:04:linux
u:02:bash
u:01:hack
Ian>sort data.txt | uniq -s 2 -w 2
d:04:linux
u:01:gnu
u:02:bash

9.临时文件命名

mktemp可以创建临时文件或者目录

Ian>mktemp
/tmp/tmp.jjRu3Hun5g
Ian>mktemp -d
/tmp/tmp.1wTP2dnulQ
Ian>mktemp -u
/tmp/tmp.EMrUeB1h6C
Ian>mktemp test.XXX
test.Pim

10.分割文件和数据

split命令

  • 基本使用

-b:按照大小分割,可以按照G,M,k,c,w分割,例如split -b 100k file

-d:分割后的文件以数字为后缀

-a:指定后缀长度

-l:按照长度分割

  • 常用方法

指定文件名前缀:split file prefix

Ian>rm -f x*
Ian>split -b 100k -d -a 2 vmware-install.pl test
Ian>ll
total 456
drwxr-xr-x 2 ian ian   4096 Apr 11 23:34 ./
drwxr-xr-x 4 ian ian   4096 Apr 11 23:26 ../
-rw-r--r-- 1 ian ian 102400 Apr 11 23:34 test00
-rw-r--r-- 1 ian ian 102400 Apr 11 23:34 test01
-rw-r--r-- 1 ian ian  22224 Apr 11 23:34 test02
-rwxr-xr-x 1 ian ian 227024 Apr 11 23:27 vmware-install.pl*
Ian>split -l 2000 vmware-install.pl 
Ian>ll
total 684
drwxr-xr-x 2 ian ian   4096 Apr 11 23:36 ./
drwxr-xr-x 4 ian ian   4096 Apr 11 23:26 ../
-rw-r--r-- 1 ian ian 102400 Apr 11 23:34 test00
-rw-r--r-- 1 ian ian 102400 Apr 11 23:34 test01
-rw-r--r-- 1 ian ian  22224 Apr 11 23:34 test02
-rwxr-xr-x 1 ian ian 227024 Apr 11 23:27 vmware-install.pl*
-rw-r--r-- 1 ian ian  57202 Apr 11 23:36 xaa
-rw-r--r-- 1 ian ian  60775 Apr 11 23:36 xab
-rw-r--r-- 1 ian ian  66419 Apr 11 23:36 xac
-rw-r--r-- 1 ian ian  42628 Apr 11 23:36 xad

csplit可以根据文件内容分割

11.根据扩展名切分文件名

${VAR%.*},删除位于%右侧的通配符所匹配的字符串。使用%对字符串进行匹配,非贪婪,从右向左找出匹配的最短结果,%%用于贪婪匹配,从右向左找出匹配的最长结果

Ian>f2="h1.h2.jpg"
Ian>echo ${file%.*}
Ian>echo ${f2%.*}
h1.h2
Ian>echo ${f2%%.*}
h1

${VAR#*.},删除位于#右侧的通配符所匹配的字符串。使用#对字符串进行匹配,非贪婪,从左向右出匹配的最短结果,%%用于贪婪匹配,从左向右找出匹配的最长结果

Ian>echo ${f2#*.}
h2.jpg
Ian>echo ${f2##*.}
jpg

12.批量重命名和移动

  • rename命令可以批量重命名文件

rename 's/jpg/JPG/g' *.jpg

rename 'y/a-z/A-Z/' *

Ian>ll
total 8
drwxr-xr-x 2 ian ian 4096 Apr 12 00:21 ./
drwxr-xr-x 5 ian ian 4096 Apr 12 00:21 ../
-rw-r--r-- 1 ian ian    0 Apr 12 00:21 a.jpg
-rw-r--r-- 1 ian ian    0 Apr 12 00:21 b.jpg
-rw-r--r-- 1 ian ian    0 Apr 12 00:21 c.jpg
Ian>rename 's/jpg/JPG/g' *.jpg
Ian>ll
total 8
drwxr-xr-x 2 ian ian 4096 Apr 12 00:30 ./
drwxr-xr-x 5 ian ian 4096 Apr 12 00:21 ../
-rw-r--r-- 1 ian ian    0 Apr 12 00:21 a.JPG
-rw-r--r-- 1 ian ian    0 Apr 12 00:21 b.JPG
-rw-r--r-- 1 ian ian    0 Apr 12 00:21 c.JPG
Ian>rename 'y/a-z/A-Z/' *
Ian>ll
total 8
drwxr-xr-x 2 ian ian 4096 Apr 12 00:32 ./
drwxr-xr-x 5 ian ian 4096 Apr 12 00:21 ../
-rw-r--r-- 1 ian ian    0 Apr 12 00:21 A.JPG
-rw-r--r-- 1 ian ian    0 Apr 12 00:21 B.JPG
-rw-r--r-- 1 ian ian    0 Apr 12 00:21 C.JPG

13.交互输入自动化

  • 发送交互式脚本进行自动化交互
#!/bin/bash
#inter.sh
read -p "Enter number:" no;
read -p "Enter name:" name;
echo "num:$no, name$name"


Ian>echo -e "1\nian" | bash inter.sh
num:1, name:ian

使用except自动化交互

#!/usr/bin/expect
#auto_expect.sh
spawn bash inter.sh
expect "Enter number:"
send "1\n"
expect "Enter name:"
send "ian\n"
expect eof


Ian>./auto_expect.sh 
spawn bash inter.sh
Enter number:1
Enter name:ian
num:1, name:ian
Ian>vim auto_expect.sh 

注意,头部使用#!/usr/bin/expect

14.使用并行进程加速命令执行

使用&后台执行

for file in list_file;

do

    md5sum $file &

done

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章