shell 学习笔记 常用命令 tr md5sum sort mktemp split expect

摘自 Linux Shell 脚本攻略 第二章 命令之乐

tr

tr可以对 来自标准输入的内容进行字符替换、字符删除以及重复字符压缩

字符的大小写转换

$ echo "HELLO WHO IS THIS" | tr 'A-Z' 'a-z'
hello who is this

对字符进行加密

tr命令可以用来加密。ROT13是一个著名的加密算法。在ROT13算法中,字符会被移动13
个位置,因此文本加密和解密都使用同一个函数

$ echo "tr came, tr saw, tr conquered." | tr 'a-zA-Z' 'n-za-mN-ZA-M'
ge pnzr, ge fnj, ge pbadhrerq.

删除字符

$ echo "Hello 123 world 456" | tr -d '0-9'
Hello  world 

字符组补集

tr -c [set1] [set2]
如果只给出了set1,那么tr会删除所有不在set1中的字符。如果也给出了set2,tr会将不 在set1中的字符转换成set2中的字符。如果使用了-c选项,set1和set2必须都给出。如果-c 与-d选项同时出现,你只能使用set1,其他所有的字符都会被删除

$ echo hello 1 char 2 next 4 | tr -d -c '0-9 \n'
 1  2  4

-d -c 同时使用时 只保留给定set字符中的字符

$ echo hello 1 char 2 next 4 | tr -c '0-9' ' '
      1      2      4 

只使用-c 时 将非字符集替换

用tr压缩字符

$ echo "GNU is       not     UNIX. Recursive   right ?" |tr -s ' ' 
GNU is not UNIX. Recursive right ?

删除字符中重复的空格

tr的灵活运用

sum.txt

$ cat sum.txt 
1
2
3
4
5

计算sum文件中所有数的和

$ cat sum.txt |echo $[ `tr '\n' '+'` 0]
15

tr ‘\n’ ‘+’ 将换行替换成+ 得到表达式 1+2+3+4+5+
再将其与0 拼接 得到表达式 1+2+3+4+5+0
最后运行该表达式得到总数

另外一个例子
test.txt

$ cat test.txt 
first 1
second 2
third 3

计算test中数字的总和

$ cat test.txt |tr -d [a-z]|echo "total $[ `tr ' ' '+'`]"
total 6

利用tr的-d选项删除文件中的字母,然后将空格替换成+

可以使用的字符类

  • alnum:字母和数字。
  • alpha:字母。
  • cntrl:控制(非打印)字符。  digit:数字。
  • graph:图形字符。
  • lower:小写字母。
  • print:可打印字符。
  • punct:标点符号。
  • space:空白字符。
  • upper:大写字母。
  • xdigit:十六进制字符。
$ echo 'coco is handsome 123 !' |tr -d [:alnum:]
    !

md5sum

计算文件的md5sum

coco.log

$ cat coco.log 
coco is handsome
$ md5sum coco.log 
7fdc4a7ed1e76c6e1e1ac2ae24fd2068  coco.log

保存校验信息

$ md5sum coco.log > coco.md5 
$ md5sum  -c coco.md5 
coco.log: OK # 校验 ok
$ vi coco.log
$ cat coco.log 
coco is handsome !
$ md5sum  -c coco.md5 
coco.log: FAILED # 原文件中添加! 校验 fail
md5sum: WARNING: 1 computed checksum did NOT match

递归校验

md5deep或sha1deep命令可以遍历目录树,计算其中所有文件的校验和。你的系统中可能 并没有安装这两个程序。可以使用apt-get或yum来安装md5deep软件包

$ md5deep -rl directory_path > directory.md5
# -r使用递归遍历
# -l使用相对路径。默认情况下,md5deep会输出文件的绝对路径

也可以结合find 命令进行递归校验

$ find directory_path -type f –print0 | xargs -0 md5sum >> directory.md5

md5与SHA-1都是单向散列算法,均无法逆推出原始数据。两者通常用于为特定数据生成 唯一的密钥

sort

sort命令能够对文本文件和stdin进行排序。它可 以配合其他命令来生成所需要的输出。uniq经常与sort一同使用,提取不重复(或重复)的行

排序一组文件

$ sort file1.txt file2.txt > sorted.txt
# 或者
$ sort file1.txt file2.txt -o sorted.txt

按照数字排序

$ sort -n file.txt

按照逆序排序

$ sort -r file.txt

按照月份排序

$ sort -M months.txt

合并两个已排序过的文件

$ sort -m sorted1 sorted2

找出已排序文件中不重复的行

$ sort file1.txt file2.txt | uniq

检查文件是否已经排序过

$ sort -C filename

依据键或者列排序

data.txt

$ cat data.txt 
1 mac 2000 
2 winxp 4000 
3 bsd 1000 
4 linux 1000
  • 根据第一列,以逆序形式排序
$ sort -nrk 1 data.txt
4 linux 1000
3 bsd 1000 
2 winxp 4000 
1 mac 2000

nr 表明按照数字顺序,采用逆序形式排序

  • 根据第二列进行排序
$ sort -k 2 data.txt
3 bsd 1000 
4 linux 1000
1 mac 2000 
2 winxp 4000 
  • 根据第二列的第二个字符位进行排序
$ sort -bk 2.2,2.3 data.txt
1 mac 2000 
2 winxp 4000 
4 linux 1000
3 bsd 1000 

与xargs组合使用

为了使sort的输出与以\0作为终止符的xargs命令相兼容,采用下面的命令

$ sort -z data.txt | xargs -0

uniq

uniq命令可以从给定输入中(stdin或命令行参数指定的文件)找出唯一的行,报告或删除 那些重复的行
uniq只能作用于排过序的数据,因此,uniq通常都与sort命令结合使用

$ cat sorted.txt bash
bash 
foss 
hack 
hack
$ uniq sorted.txt bash
bash 
foss 
hack

只显示唯一的行

$ uniq -u sorted.txt 
bash 
foss
# 或者
$ sort unsorted.txt | uniq -u

统计各行出现的次数

$ sort sorted.txt |uniq -c
      1 bash
      1 foss
      2 hack

找出重复的行

$ sort sorted.txt |uniq -d
hack

灵活使用

uniq -s -w 没弄懂 先空着

mktemp

创建临时文件

$ mktemp
/tmp/tmp.p2LSrnqLnY

创建临时目录

$ mktemp -d
/tmp/tmp.vz0dURj7ou

仅生成文件名 不创建对应文件

$ mktemp -u
/tmp/tmp.s1kyZszp1i

基于模板创建临时文件名

$ mktemp test.XXX
test.EH2

如果提供了定制模板,X会被随机的字符(字母或数字)替换。注意,mktemp正常工作的前 提是保证模板中至少要有3个X

split

split命令可以用来分割文件。该命令接受文件名作为参数,然后创建出一系列体积更小的 文件,其中依据字母序排在首位的那个文件对应于原始文件的第一部分,排在次位的文件对应于 原始文件的第二部分,以此类推

分割文件

$ split -b 10k data.file
$ ls
data.file  xaa  xab  xac  xad  xae  xaf  xag  xah  xai  xaj

split默认使用字母后缀。如果想使用数字后缀,需要使用-d选项。此外, -a length 可以指定后缀长度

分割文件并指定后缀格式

$ split -b 10k data.file -d -a 4
$ ls
data.file x0009  x0019  x0029  x0039  x0049  x0059  x0069  x0079

分割文件指定前后缀格式

$ split -b 10k data.file -d -a 4 split_file
$ ls
data.file split_file0002 split_file0005 split_file0008 split_file0000 split_file0003 split_file0006 split_file0009 split_file0001 split_file0004 split_file0007

按照行数分割文件

分割成多个文件,每个文件包含10行

$ split -l 10 data.file

csplit的使用

$ csplit server.log /SERVER/ -n 2 -s {*}  -f server -b "%02d.log"
$ rm server00.log
$ ls
server01.log  server02.log  server03.log  server.log
  • /SERVER/ 用来匹配特定行,分割过程即从此处开始。
  • /[REGEX]/ 用于描述文本模式。它从当前行(第一行)一直复制到(但不包括)包含SERVER
    的匹配行。
  • {*} 表示根据匹配重复执行分割操作,直到文件末尾为止。可以用{整数}的形式来指定分
    割执行的次数。
  • -s 使命令进入静默模式,不打印其他信息。
  • -n 指定分割后的文件名后缀的数字个数,例如01、02、03等。
  • -f 指定分割后的文件名前缀(在上面的例子中,server就是前缀)。
  • -b 指定后缀格式。例如%02d.log,类似于C语言中printf的参数格式。在这里:文件
    名 = 前缀 + 后缀,也就是server + %02d.log。

根据拓展名切分文件名

提取文件名

$ name=coco.log
$ echo ${name%.*}
coco
$ echo ${name#*.}
log

${VAR%.*} 的含义如下

从$VAR中删除位于%右侧的通配符(在上例中是.*)所匹配的字符串。通配符从右向左进 行匹配。
给VAR赋值,即VAR=sample.jpg。通配符从右向左匹配到的内容是.jpg,因此从$VAR中 删除匹配结果,得到输出sample。

%属于非贪婪(non-greedy)操作。它从右向左找出匹配通配符的最短结果。还有另一个操作 符%%,它与%相似,但行为模式却是贪婪的,这意味着它会匹配符合通配符的最长结果

$ VAR=hack.fun.book.txt
$ echo ${VAR%.*}
hack.fun.book
$ echo ${VAR%%.*}
hack

多个文件的重命名与移动

#!/bin/bash
#文件名: rename.sh
#用途: 重命名 .jpg 和 .png 文件
    count=1;
    for img in `find . -iname '*.png' -o -iname '*.jpg' -type f -maxdepth 1` # 在当前目录查找多有 png 以及 jpg文件
    do
      new=image-$count.${img##*.} # 拼接新名字 image-1.jpg
      echo "Renaming $img to $new"
      mv "$img" "$new"
      let count++
done

拼写检查与词典操作

#!/bin/bash
#文件名: checkword.sh
word=$1
grep "^$1$" /usr/share/dict/british-english -q if [ $? -eq 0 ]; then # 通过grep 查找文件中是否存在文件中
      echo $word is a dictionary word;
    else
      echo $word is not a dictionary word;
    fi

aspell

$ echo 'coco is handsoma' |aspell list
handsoma

交互输入自动化

#!/bin/bash
# backup.sh
# 使用后缀备份文件。不备份以~开头的临时文件
read -p " What folder should be backed up: " folder
read -p " What type of files should be backed up: " suffix 
find $folder -name "*.$suffix" -a ! -name '~*' -exec cp {} $BACKUP/$LOGNAME/$folder
echo "Backed up files from $folder to $BACKUP/$LOGNAME/$folder"

$ echo -e "notes\ndocx\n" | ./backup.sh
Backed up files from notes to /BackupDrive/MyName/notes

expect

#!/usr/bin/expect 
# 不是!/bin/bash 解释器
# 文件名: automate_expect.tcl 
spawn ./backup .sh # 执行backup.sh 脚本
expect { 
      "*folder*" {
         send "notes\n"
         exp_continue # 未检索到folder 也会继续往下执行
	  } 
	  "*type*" {
         send "docx\n"
         exp_continue
      }
}

利用并行进程加速命令执行


#/bin/bash
#文件名: generate_checksums.sh 
PIDARRAY=()
for file in File1.iso File2.iso;do
md5sum $file &
  PIDARRAY+=("$!") # $! Shell最后运行的后台Process的PID(后台运行的最后一个进程的进程ID号)
done
wait ${PIDARRAY[@]} # 等待后台结束后退出脚本

检查目录以及其中的文件与子目录

查看目录的树状图

$ find . -exec sh -c 'echo -n {} | tr -d "[:alnum:]_.\-" | tr "/" " "; basename {}' \;
.
 .idea
  workspace.xml
  misc.xml
  .gitignore
  inspectionProfiles
   Project_Default.xml
   profiles_settings.xml
  modules.xml
  for_fun.iml
 aa.json
 coco.py
 main.py
 text.txt

! 最后basename 输出文件名 没明白怎么添加的行首空格

查看各文件夹下文件数量

for d in `find . -type d`;do  # 获取文件夹列表
	echo `find $d -type f |wc -l` file in  $d # 遍历文件夹内数量 统计
done
11 file in .
7 file in ./.idea
2 file in ./.idea/inspectionProfiles
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值