shell的一些基本命令(使用的小技巧)

我们可以在命令行界面解决很多问题,此次介绍一些使用命令
1、用cat命令进行拼接
cat命令通常用于读取,显示或拼接文件内容,不过cat的作用远不止与此。
cat命令是一个经常使用到的命令,本身表示concatenate(拼接的意思)
1.打印多个文件内容
我们可以使用cat命令同时打印多个文件内容



2.从标准输入中进行读取
想要从标准中读取需要使用管道操作符
3.摆脱多余的空白行
有时候文本文件可能包含多出连续的空白行
cat -s file # 压缩相邻的空白行
单独有一个一行空白行的时候,无法进行删除
此外,也可以使用tr命令删除所有的空白行,tr命令有移除替换文本的功能
4.将制表符显示为 ^I #注这是一个大写字母I
单从视觉上很难讲制表符同连续的空格区分开。如果用python编写程序时,用与代码缩进的制表符和空格具有特殊意义的,
cat有一个特性,可以将制表符着重标记出来。



5.行号,添加行号
使用cat命令的-n选项会在输出的每一行内容之前加上行号,但是cat命令并不是在修改文件内容
cat -n file
-n选项甚至会为空白行加上行号,如果想要跳过空白行,使用选项-b

2、录制并回放终端会话
利用script和scriptreplay命令,可以录制命令的次序和时序,将相关记录在文本文件中
script -t 2> timing.log -a output.session
两个配置文件被当做 script 命令的参数。其中一个文件(timing.log)用于存储时序信息,
描述每一个命令在何时运行;另一个文件(output.session)用于存储命令输出。 -t 选项用于将时
序数据导入 stderr 。 2> 则用于将 stderr 重定向到timing.log。
利用这两个文件: timing.log(存储时序信息)和output.session(存储命令输出信息) ,我们
可以按照下面的方法回放命令执行过程:
$ scriptreplay timing.log output.session
# 按播放命令序列输出

3、文件查找与文件列表
find命令在命令行工具箱中很重要
find命令的工作模式,沿着文件层次结构向下遍历,匹配符合条件的文件,执行相应的操作。
1.列出当前目录及子目录下所欲的文件和文件夹
find base_path
其中bash_path可以放在任意位置,就是说任何一个目录,find会从该位置开始向下查找。
find . -print #打印文件的目录和列表
注: . 符号表示当前目录 .. 符号表示父目录
-printf指明打印出匹配文件的文件名(路径) 。当使用-print时,'\n'作为对输出的文件名进行分隔
即使忽略-print,find仍会打印文件名
-print0指明使用'\0' 作为匹配的文件名间的定界符,当文件名中包含换行符时,无效
2.根据文件名或者正则表达式进行搜索
-name 参数指定里文件名所必须匹配的字符串
find /home/ -name "*.txt" -print #找到目录下以txt结尾的文件
注意文件目录的路径问题
iname 参数和name参数的使用方法相同,只不过在匹配字符时会忽略大小写
如果想要匹配多个条件中的一个,可以采用OR条件操作
$ ls
new.txt some.jpg text.pdf
$ find . \( -name "*.txt" -o -name "*.pdf" \) -print
./text.pdf
./new.txt
上面的代码会打印出所有的.txt和.pdf文件,是因为这个 find 命令能够匹配所有这两类文件。
\( 以及 \) 用于将 -name "*.txt" -o -name "*.pdf" 视为一个整体。
-path参数可以使用通配符来匹配文件路径。-name总是用给定的文件名进行匹配。
-path则将文件路径作为一个整体进行匹配
$ find /home/users -path "*/slynux/*" -print
这会匹配以下路径:
/home/users/list/slynux.txt
/home/users/slynux/eg.css
选项 -regex 的参数和 -path 的类似,只不过 -regex 是基于正则表达式来匹
配文件路径的。
正则表达式是通配符匹配的高级形式,它可以指定文本模式 ,我们借助这种模式来匹配文本及进行打印
下面的命令匹配.py或.sh文件:
$ ls
new.PY next.jpg test.py
$ find . -regex ".*\(\.py\|\.sh\)$"
./test.py
类似地, -iregex 可以让正则表达式忽略大小写。例如:
$ find . -iregex ".*\(\.py\|\.sh\)$"
./test.py
./new.PY
3.否定参数
find也可以用“!”否定参数的含义
find . ! -name "*.txt" -print #匹配所有不以.txt结尾的文件名
4.基于目录深度的搜索
find命令在使用时会遍历所有的子目录,可以使用-maxdepth 和-mindepth来限制find命令遍历的目录深度
如果只允许find在当前目录下的查找,深度可以设置为1,当需要向下两级时,深度可以设置为2,以此类推
可以用-maxdepth指定最大深度,也可以指定一个最小的深度,告诉find应该从此处开始向下查找
find . -maxdepth 1 -name "f*" -print
该命令列出当前目录下的所有文件名以f打头的文件。即使有子目录,也不会被打印或遍历。与
之类似, -maxdepth 2 最多向下遍历两级子目录。
-mindepth 类似于 -maxdepth ,不过它设置的是 find 开始遍历的最小深度。这个选项可以
用来查找并打印那些距离起始路径一定深度的所有文件。例如,打印出深度距离当前目录至少两
个子目录的所有文件:
$ find . -mindepth 2 -name "f*" -print
./dir1/dir2/file1
./dir3/dir4/f2
即使当前目录或dir1和dir3中包含有文件,它们也不会被打印出来
-maxdepth 和 -mindepth 应该作为find的第三个参数出现,如果作为第四个或之后的参数,
就可能影响到find的效率
5.根据文件类型搜索
Linux系统将一切文件,文件具有不同的类型,例如普通文件,目录,字符设备,块设备,符号链接,硬链接,套接字
和管道文件等
-type可以对文件搜索进行过滤。
只列出所有的目录
find . -type d -print
6.根据文件时间进行搜索
访问时间(-atime):用户最近一次访问文件的时间
修改时间(-mtime):文件内容最后一次被修改的时间
变化时间(-ctime):文件元数据(例如权限或所有权)最后一次改变的时间
注:在Linux中并没有创建时间的概念
-atime 、-mtime 、-ctime 可以作为find的时间的选项,可以用整数值指定,单位是天
这些数值通常还带有- + :-号表示小于 +号表示大于
-amin(访问时间)
-mmin(修改时间)
-cmin(变化时间)
这几个选项的计数单位是以分钟作为计量单位的
-newer 指定一个用于比较时间戳的参考文件,然后找出比参考文件更新的(更近的修改时间)所有文件
7.基于文件大小的搜索
根据文件的大小可以使用 size参数
$ find . -type f -size +2k
# 大于2KB 的文件
$ find . -type f -size -2k
# 小于2KB 的文件
$ find . -type f -size 2k
# 大小等于2KB
同样还可以使用其他文件大小单元
b 块
c 字节
w 字
k 1024字节
M 1024K字节
G 1024M字节
8.删除匹配的文件
-delete选项可以用来删除find查到的匹配文件
删除查找目录下所有的.txt文件
find /home -type f -name "*.txt" -delete
9.基于文件权限和所有权的匹配
-perm选项指明find应该只匹配具有特定权限值的文件
find /home -type f -perm 644 -print
-user USER选项能够找到由某个指定用户所拥有的文件
参数USER可以是用户名或UID
find /home -type f -user root #查找目录下root用户拥有的所有的文件
10.利用find命令执行命令或动作
find命令可以借助exec选项和其他命令进行结合,-exec选项是find最强大特性之一



在图片中是想要找到目录下以.sh结尾的文件,并且大小为2K,最后将文件内容用cat命令显示出来
命令中首先是有一个错误,空格的位置, {}是一个和-exec选项搭配使用的特殊字符串,对于每一个匹配的
文件,{}会被替换成相应的文件名。
-exec后名可以接任何命令,{}表示一个匹配,对于任何一个匹配的文件名,{}会被该文件名替换
如果想要使用-exec结合多个命令,但是在exec选项的参数中无法直接使用多个命令,他只接受单个命令
不过可以吧多个命令写到一个shell脚本中然后再爱exec中使用这个脚本
-exec ./commands.sh {} \;
-exec 能够同 printf 结合来生成有用的输出信息。例如:
$ find . -type f -name "*.txt" -exec printf "Text file: %s\n" {} \;
11.让find跳过指定的目录
在搜素目录的时候,有时候为了提高性能,需要跳过一些子目录。
将某些文件或目录从搜素过程中排除在外的技巧称为修剪
$ find devel/source_path \( -name ".git" -prune \) -o \( -type f -print \)
# 不使用\( -type -print \), 而是选择需要的过滤器
以上命令打印出不包括在.git目录中的所有文件的名称(路径)。
\( -name ".git" -prune \) 的作用是用于进行排除,它指明了 .git目录应该被排除在外,
而 \( -type f -print \) 指明了需要执行的动作。这些动作需要被放置在第二个语句块中(打
印出所有文件的名称和路径)。

4、xargs命令
可以使用管道将一个命令stdout重定向到另一个命令的stdin
但是如过有些命令只能以命令行参数的形式接受数据,无法通过stdin接受数据流,无法使用管道来
提供那些只有通过命令行参数才能提供的数据
xargs命令可以将标准输入数据转换成命令行参数。
xargs 能够处理stdin并将其转换为特定的命令行参数 ,xargs也可以将单行或多行文本输入转换成其他格式,
如单行变多行或多行变单行
xargs可以作为一种替代,作用类似find命令中的exec选项
1.将多行输入转换成单行输出
只需要将换行符移除,再用“”进行代替,就可以实现多行输入的转换。
‘\n’被解释成一个换行符,换行符就是多行文本键的定界符。 利用xargs,使用空格符替换掉换行符



2.将单行输入转换成多行输出
指定每行最大的参数的数量n,我们可以将任何来自stdin的文本划分成多行,每行n个参数
每一个参数都是有“ ”(空格)隔开的字符串


3.指定特定的定界符
-d选项可以指定一个定制的定界符
上面是随机输入一串字符,包含多个字母d,可以使用-d选项将d作为输入的定界符
默认情况下,xargs采用内部字段分隔符(空格符)作为定界符



4. 读取stdin,将格式化参数传递给命令
如果想要把一个包含着参数列表文件中的内容做为参数传递给即将使用的下一个命令,但是
想要给参数固定一个格式,比如我想一次传递两个参数,或者是一次传递三个参数的时候,就需要使用
xargs命令进行参数的格式化提供。
INPUT | xargs -n X cmd
INPUT指的是想要输入作为参数的文件或者是其他内容,X是一个数字,就是说X就是你想要指定一次想要提供的参数的个数
xargs命令就是把你一共提供的参数在分配后传递给下一个命令
5.结合find使用xargs
注:只要是find的输出作为xargs的输入,就必须将-print0 和find结合使用,以字符NULL(\0)来分隔输出
6.结合stdin,运用while语句和子shell
xargs只能以有限的几种方式来提供参数,而且不能为多组命令提供参数
$ cat files.txt | ( while read arg; do cat $arg; done )
# 等同于cat files.txt | xargs -I {} cat {}
在 while 循环中,可以将 cat $arg 替换成任意数量的命令,这样我们就可以对同一个参数
执行多条命令。也可以不借助管道,将输出传递给其他命令。这个技巧能够适用于各种问题场景。
子shell操作符内部的多个命令可作为一个整体来运行。
$ cmd0 | ( cmd1;cmd2;cmd3) | cmd4
如果 cmd1 是 cd / ,那么就会改变子shell工作目录,然而这种改变仅局限于子shell内部。 cmd4
则完全不知道工作目录发生了变化。

5、tr命令
tr命令可以对来自标准输入的内容进行字符替换,字符删除以及重复字符压缩等。可以将一组字符变成另一种字符,
所以一称为转换命令。
tr只能通过stdin,无法通过命令行参数来接受输入。
tr options set1 set2
将来自stdin的输入字符从set1映射到set2,然后将输入写入到stdout。
set1和 set2 是字符类或字符集。如果两个字符集的长度不相等,那么 set2 会不断重复其最后一个字
符,直到长度与 set1 相同。如果 set2 的长度大于 set1 ,那么在 set2 中超出 set1 长度的那部分
字符则全部被忽略。
1.大写转换成小写


2.可以给数据进行简单的加密


这样就进行了简单的加密过程。
3.删除字符
-d选项可以通过指定需要被删除的字符集合,将出现在stdin中的特定字符清除
cat file.txt | tr -d '[set1]'
#只使用set1,不使用set2


4.字符集补集
-c选项使用set1的补集
tr -c [set1] [set2]
set1的补集意味着这个集合包含set1中没有的所有的字符。



3.用tr压缩字符
连续的重复字符压缩成单个字符
-s选项可以压缩输入中重复的字符,经常需要从事的一项任务就是压缩空白字符。


tr -s '[set]'
使用tr命令将文件中的数字列表进行相加


上面的命令中,tr命令将'\n' 替换成’+‘,这样会得到1+2+3+4+这样的一个字符串,但是这样结尾会
多一个字符+,为了抵消这个多出来的+ ,我们再追加一个0。
$[ operation ] 执行算数运算,这样就能计算出来结果了。
同样还可以使用tr命令删除多余的换行符。
4.字符类
tr可以使用集合一样使用各种不同的字符类
alnum: 字母和数字
alpha: 字母
cntrl: 控制字符(非打印)
digit: 数字
graph: 图形字符
lower: 小写字母
print: 可打印字符
space: 空白字符
upper: 大写字母
xdigit: 十六进制字符
tr [:class:] [:class:]
例如:
tr '[:lower:]' '[:upper:]'

6、排序、单一与重复
同文本文件打交道,少不了需要用到排序。
sort命令能够对文本文件和stdin进行排序操作,uniq是一个经常与sort一同使用的命令。
sort命令包含大量的选项,能够对文件数据进行各种排序。使用uniq命令,sort命令是必不可少的,uniq命令要求输入的数据必须经过排序
1.对一组文件进行排序
sort file1.txt file2.txt > sorted.txt
或者是
sort file1.txt file2.txt -o sorted.txt
2.按照数字顺序进行排序
sort -n file.txt
3.按照逆序进行排序
sort -r file.txt
4.按照月份进行排序(依照一月,二月,三月)
sort -M months.txt
5. 合并两个已经排序过的文件
sort -m sorted1 sorted2
6.找出已经排序文件中不重复的行
sort file1.txt file2.txt | uniq
7. 检查文件是否已经排序
sort -C filename
8.依据键或列进行排序
-k选项指定了排序应该按照哪一个按键来进行。键指的是列号,而列号就是执行排序是的依据。



在上面的命令中需要留意的是按数字顺序进行排序的选项-n。sort命令对于字母表排序和数字排序有不同的处理方式
通常在默认的情况下,键就是文本文件中的列,列与列之间用空格分隔。但是有时候,需要选取特定范围内的一组字符。
sort -k 2,3 filename #取第2和第3个字符进行读取
9.忽略空格
-b选项用来忽略文件中的前导空白行
-d选项用于指明以字典序进行排序
10.uniq
uniq命令通过消除重复内容,从给定的输入中找出唯一的行。也可以找出输入中出现的重复行。
注:uniq只能用于排过序的数据输入,所以uniq要么使用管道,要么将排过序的文件作为输入,与sort命令集合使用。



或者是 sort unsorted.txt | uniq
只显示唯一的行
-u选项可以在显示的时候,只显示唯一的行(在输入文件中没有重复出现的行)



统计各行在文件中出现的次数
-c选项可以统计每一行在文件中出现的次数,便于分出哪些内容是重复的。



可以只输出文件中重复的行
-d选项可以找出文件中重复的行并且打印到屏幕上
可以指定键:(即指定列)
结合-s和-w选项来指定键
-s指定可以跳过前n个字符
-w指定用于比较的最大字符数
命令输出作为 xargs 命令的输入时,最好为输出的各行添加一个0值字节(zero-byte)
终止符。在将 uniq 命令的输入作为 xargs 的数据源时,同样应当如此。如果没有使用0值字节终
止符,那么在默认情况下, xargs 命令会用空格作为定界符分割参数。例如,来自 stdin 的文本
行“this is a line”会被 xargs 当做包含4个不同的参数,但实际上它只是一个单行而已。如果使用
0值字节终止符,那么 \0 就被作为定界符。

7、分割文件和数据
在某些情况下,必须把文件分割成多个更小的片段。
文件大小为100KB。你可以将该文件分割成多个大小为
10KB的文件,方法如下:
$ split -b 10k data.file
$ ls
data.file xaa xab xac xad xae xaf xag xah xai xaj
-b选项可以指定分割每个片段的大小
还可以使用-d参数,可以用数字为后缀。
-a length 可以指定后缀长度



1.为分割后的文件指定文件名前缀
那些分割后的文件都有一个文件名前缀x。可以通过提供一个前缀名来使用自己的文件名前缀。



如果不想按照数据块大小来分割文件的话。使用-l选项
split -l 10 filename #分割成多个文件,每个文件包含10行
2.csplit工具
能够依据指定的条件和字符串匹配选项对日志文件进行分割。
csplit 是 split 工具的一个变体。 split 只能够根据数据大小或行数分割文件,而 csplit
可以根据文本自身的特点进行分割。是否存在某个单词或文本内容都可作为分割文件的条件。

8、根据文件扩展名切分文件名
有一些脚本是依据文件名进行各种处理的。可能需要在保留扩展名的同时修改文件名,转换文件格式或提取部分文件名。
1. % 符号
借助%操作符可以轻松将名称部分从“名称.扩展名”这种格式中提取出来。


2. #符号
借助#操作符可以将文件名的扩展名提取出来。


${var%.*} 解释
指的是从变量var的值中删除位于%右侧的通配符(此例中是 .*),所匹配的字符串。通配符从右向左进行匹配。
%属于非贪婪模式,从右向左找出匹配统配符的最短结果。还有另外一个操作符%% ,他的行为模式是贪婪的,
他会匹配符合条件的最长的字符。



${var#*.}
和%类似,删除位于#右侧的通配符所匹配的字符串。通配符从左向右进行匹配。
同样的##也有一个相对应的贪婪操作符



因为文件名中可能包含多个’.‘字符,所以相较于#,##更适合于从文件名中提取扩展名

9、批量重命名和移动
重命名文件是我们经常会碰到的一项工作。
脚本见 脚本收录 -04
1.rename 命令
将*.JPG 更名为*.jpg
rename *.JPG *.jpg
将文件名中的空格替换成字符"_"
rename 's/ /_/g' *
* 号是用于匹配目标文件中的通配符,可以以*.txt 或者是其他样式出现
转换文件名的大小写
rename 'y/A-Z/a-z/' *

10、交互输入自动化
先写一个读取交互式输入的脚本,然后用这个脚本进行自动化的演示:
#!/bin/bash
#文件名: interactive.sh
read -p "Enter number:" no ;
read -p "Enter name:" name
echo You have entered $no, $name;
执行脚本的时候可以这样操作
$ echo -e "1\nhello\n" | ./interactive.sh
You have entered 1, hello
也可以实现把所有的变量都写入文件中然后再利用管道输出
使用expect命令
默认情况下,expect并没有附带与常见的发行版,必须使用软件包进行安装

expect 等待特定的输入提示,通过检查输入提示来发送数据。
#!/usr/bin/expect
#文件名: automate_expect.sh
spawn ./interactive.sh
expect "Enter number:"
send "1\n"
expect "Enter name:"
send "hello\n"
expect eof
运行结果如下:
$ ./automate_expect.sh
在这个脚本中:
 spawn 参数指定需要自动化哪一个命令;
 expect 参数提供需要等待的消息;
 send 是要发送的消息;
 expect eof 指明命令交互结束。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值