欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Linux Shell 学习笔记(二) 命令

程序员文章站 2022-03-03 22:31:43
...

Linux Shell 学习笔记(二) 命令

环境: Centos 7 bash

本博文介绍Linux中经常使用的命令

1. cat命令

cat file1 file2 .. file3
#将多个文件的内容输出到stdout

cat命令不仅可以将文件内容输出到stdout,还可以将stdin中获得输入进行输出

echo "this is form stdin" | cat - fileName
# - 用来指代stdin

cat 压缩空白行 cat -s fileName

cat 标记行号 cat -n fileName

2. 录制与回放终端会话

2.1 script命令

# 开始录制命令
script -t 2>timing.log -a output.session

-t 将时序信息输出到stderr
2>timming.log 将stderr重定向到timming.log
-a output.session 将命令输出存储到output.session

#接下来所有的终端输入输出都会被记录在上述两个文件中,直至用户输入exit结束录制

2.2 scriptreplay

scriptreplay timming.log ouput.session   
# 输出录制的终端活动

3. 文件查找与文件列表 find命令

# 列出目录及子目录中的所有文件和文件夹
find pathVar                默认使用参数 -print
find pathVar -print         多行输出
find pathVar -print0        单行输出


# 根据文件名/正则查找文件
find pathVar -name "*.txt" -print
find pathVar -iname "*.txt" -print      # 在查找试忽略文件名参数的大小写

# 使用多个查找条件
find pathVar \( -name "*.txt" -o -name "*.sh" \) -print

# 匹配路径
find pathVar -path "*mn" -print
#将匹配pathVar目录下路径或文件命中含有mn的所有文件

# 正则表达式
find pathVar -regex ".*"        # 匹配所有无内件和文件夹
find pathVar -regex ".*\.sh"    # 匹配shell脚本

# 否定
find pathVar ! -name "*.txt"    # 匹配目录下所有非txt的文件

# 搜索目录深度
-maxdepth       #搜索结束目录层数
-mindepth       #搜索起始目录层数


# 指定搜索文件类型
-type typeVar
参数:
        d       目录
        f       普通文件
        c       字符设备文件
        b       块设备文件
        l       符号链接
        s       套接字 
        p       FIFO


# 根据文件时间进行搜索
linux文件有三个时间戳
-访问时间(-atime)               文件最近一次被访问的时间戳
-修改时间(-mtime)               文件最近一次被修改的时间戳
-变化时间(-ctime)               文件元数据(权限所有权等)改变的时间  

find . -type f -atime  7 -print         # 恰好在7天前被访问过的文件
find . -type f -atime -7 -print         # 在7天内被访问过的文件
find . -tyoe f -atime +7 -print         # 超过7天被访问过的文件

'-7' 代表小于7
'+7' 代表大于7

上面的三个参数都是以天为单位,还有一分钟为单位的,-amin(访问时间),-mmin(修改时间), -cmin(变化时间)



# 基于文件大小的搜索
-size sizeNum
find . -type f -size -2k        # 查找小于2kb的普通文件
find . -type f -size +2k        # 查找大于2kb的普通文件

除了以k为单位,还有(b--块512字节),(c--字节),(w--字),(k--千字节)



# 基于文件权限的搜索
find . -type f -perm 644 -ptint


# 基于文件所有用户搜索
find . -type -user root -print


# 基于查找结果执行命令或动作
-exec command {} \;
{} 对应每一个匹配的文件名,或者说是执行command命令的文件集
其他为固定格式
command只能是一条命令,但是我们可以把命令集写入到sheell脚本中,然后执行这个脚本文件,打到可以执行多条命令的目的

# 跳过搜索
# 对于不想搜索的目录,如.git,可以跳过
 find /home -path /home/sep -prune -o -name "tmp.txt" -print

4. xargs

管道只能提供简单的输入输出流重定向,对于命令参数的调用,就无能为力。xargs可以将输入数据装化为命令行参数

example.txt文件内容:
1 2 3 4 5 6
11 12 13    


# 将文本单行输出 
cat example.txt | xargs                 # 将'\n' 替换为 ” “

# 将文本格式化输出
cat example.txt | xargs -n 3            # 默认定界符 空格

# 指定定界符 分割参数
echo "ShellXShellXShell" | xargs -d X
####输出 Shell Shell Shell 

xargs重复执行命令
args.txt文件内容
arg1
arg2
arg3

myEecho.sh内容
#!/bin/bash
echo $*
# 输出脚本接收到的参数


# 将args.txt中的三个参数,依次传递给myEcho.sh脚本
cat args.txt | xargs -n 1 ./myEcho.sh


# 应对 ./myEcho.sh -p arg1 1 的命令格式,参数只有arg1是可变的
# xargs有参数-I提供对上面命令格式的支持
cat args.txt | xargs -I {} ./myEcho.sh -p {} 1
-I {} 定义替换符:用args.txt里的内容替换./myEcho.sh -p {} 1中的{}

5. tr

tr(reanslate)可以将标准输入进行替换、删除以及压缩

# 替换
# tr srcCharSet dstCharSet
echo "THIS IS MY WORDS" | tr 'A-Z' 'a-z'

# 简单加密
echo "24354673" | tr '0-9' '8967452301'
###输出 64754237

# 删除
echo "AAAAAAAAbbAAAbbbAAAAb" | tr -d 'b' 
###输出 AAAAAAAAAAAAAAA

# 补集
-C set将得到set集合的补集
echo hello 123 world | tr -d -C '0-9'
###输出 123

# 压缩字符
通常情况下,删除多余的空行空格
echo "AA       BB     CC " | tr -s " "
输出 AA BB CC

6. 小综合

6.1 xargs+find

# 删除文件
find . -type f -name "*.txt" -print | xargs rm -f
#上文未指定定界符,可能会造成误删
#正确的做法
find . -type -f -name "*.txt" -print0 | xargs -0 rm -f
-0 参数指定定界符为"\0"

6.2 while+(子shell)

cat args.txt | (while read arg;do statements; done)
将args.txt中的行内容分配到子进程中;子进程可以对参数执行多条命令

7. 校验和与核实

校验和一般用于网络数据传输

校验和技术:md5sum sha1sum

# md5sum使用
md5sum fileName
## 输出: 96cf433c1d760bb1d59e486b4207e22f  fileName

# 输出重定向
md5sum fileName > md5Result.md5

# md5sum验证
md5sum -c md5Result.md5

# sha1sum用法与md5sum相同
#只是注意 sha1sum的结果保存在.sha1为后缀的文件中

# 对于目录的检验和计算可以使用sha1deep和md5deep实现

8. 排序、单一与重复

sort命令可以帮助我们对文本文件和stdin进行排序操作

uniq命令可以从文本文件或stdin中提取一行

8.1 sort命令

# sort命令使用
sort file1 ... file2 > sortResult.txt
## 将多个文件中的每一行进行排序,结果是有序的包含所有文件内容的文件

# 找出已排序文件中不重复的行
cat sortResult.txt | uniq > uniqResult.txt


# 按照数字顺序进行排序
sort -n fileName

# 逆序排序
sort -r fileName

# 按照月份进行排序
sort -M fileName

# 判断文件是否被排序过
sort -C fileName
echo $?                            # 输出 0,则文件被排序过


# 依据键或者列进行排序
文件example.txt内容
1   mac     1000
2   linux   4000
3   winxp   3000

# 以第一列逆序排序
sort -rk 1 example.txt

# 指定键的起始和终结位置(应对键与键之间没有空格分隔的情况)
sort -k 2,4 example.txt
# 2,4指定键的起始位置和终结位置

# 使sort的输出的结束符为‘\0’ 与xargs命令兼容
sort -z example.txt | xargs -0

# 其他参数
-b      # 忽略空格等不必要的字符
-d      # 以字典序排序

8.2 uniq命令

uniq只能以排序过的数据为输入

# 对重复行只做一次输出
sort fileName | uniq    
uniq sortedFile

# 输出只出现过一次的行
sort fileName | uniq -u
uniq -u sortedFile

# 统计各行出现的次数
sort fileName | uniq -c
uniq -c sortedFile


# 输出出现多次的行
uniq -d sortedFile

uniq -s 2 -w 5 sortedFile
## -s 指定 跳过每行多个字符
## -w 指定 最大的比较字符数
### 上面的命令说明 从每行的第三个字符开始比较,最多比较5个字符到第8个字符

# 输出以‘\0’为行终结符的数据 兼容xargs命令
uniq -z sortedFile

9. 临时文件命名与随机数

在编写脚本时,我们需要储存许多临时变量,最好将临时数据储存在/tmp下,该目录下的内容将在下次系统启动时被删除

temp_file = "/tmp/var.$$"
	$$会被理解为当前运行脚本的进程ID
9.1 文件分割
# 生成测试文件
dd if=/dev/zero bs=100k count=1 of=data.file
### 创建大小为100kb,内容全部是0填充的文件

# 分割
split -b 10K file.data
### 分割后的文件名会有一个字母作为后缀,如果想使用数字作为后缀,使用参数-d指定

参数 -a length指定后缀长度
split命令的最后一个参数可以指定文件的前缀

# 根据文件的行数分割
split -l 10 file.data
### 分割后的每个文件中只有原文件的10行内容    
9.1.1 csplit
csplit可以依据指定的条件和字符串匹配对log文件进行分割

csplit server.log /SERVER/ -n 2 -s {*} -f server -b "%02d.log"

/SERVER/用来匹配某一行,分割从此行开始
{*}  根据匹配循环执行分割,直至文件末
-s 静默模式,不打印其他信息
-f server 指定文件名前缀
-b "%02d.log" 指定文件后缀名格式
9.2 根据扩展名切分文件名

借助操作符 % 可以轻松的将名称部分从”名称.扩展名”中提取出来

#脚本实现
file_name="sample.jpg"
name=${file_name%.*}
echo $name

借助操作符 # 可将扩展名从”名称.扩展名”中提取出来

#脚本实现
file_name="sample.jpg"
name=${file_name#*。}
echo $name
实现原理
name=${file_name%.*}

${file_name%.}的语义是删除占位符%右侧的通配符(.)所匹配的字符串,通配符自右向左匹配

% 非贪婪匹配,匹配到字符串即结束,自右向左进行匹配

%% 贪婪匹配,匹配最长的字符串,自右向左进行匹配

# ##与% %%相似,匹配自左向右进行

10. 批量重命名和移动

find rename mv三个命令灵活使用

#示例脚本
count=1
for img in *.jpg *.png
do
new=image-$count.${img##*.}

mv "$img" "$new" 2 > /dev/null

if [$? -eq 0];
then 
echo "renaming $img to $new"
let count++
fi

done

11. 交互式输入自动化

# 命令脚本
#! /bin/bash
#fileName script.sh

read -p "input a number" numb;
read -p "input a word" myword;
echo $numb " " $myword

执行上述脚步,我们要依次输入一个数字和一个单词。bash以一个换行符为输入结束标志。那么我们可以通过echo实现自动化输入

echo -e "1\nmyWord\n" | ./script.sh
## -e参数 指定生成输入序列

如果需要输出的参数过多或者过长,可以将参数写入文件,再将数据从文件传递到命令

echo -e "1\nmyWord\n" > arg.data
./script.sh < arg.data
11.1 expect命令

该命令需要安装

#!/usr/bin/expect
# fileName "s.sh"

spawn ./script.sh
expect "number"
send "1\n"
expect "word"
send "ssss\n"
expect eof

# 注意 #!/usr/bin/expect
# spawn                 指定要自动化执行的脚本
# expect "number"       send参数以前,要等待的消息
# send "1\n"            要发送的消息,注意换行符
# expect eof            交互命令结束