linux shell脚本攻略总结(二)

1 cat技巧

$ cat -s file  #删除多余的空白行
$ cat -T file  #将制表符显示为^|
$ cat -n file  #在行首加行号打印

2 录制并回放终端回话

录制命令

$ script -t 2> timing.log -a output.session
$ type commands
$ ...
$ exit
#timing.log存放时序信息,output.session存储命令输出;-t将时序数据导入stderr。

回放命令

scriptreply timing.log output.sesssion

3 文件查找

find . -name "*.txt" -print #打印当前目录以.txt结尾的文件名

find . -iname "*example.*" -print   #忽略大小写

find . \( -name "*.txt" -o -name "*.pdf" \) -print  #-o表示或(OR)

find /home/users -path "*/gycg/*" -print    #打印含有/gycg/的路径

find . -regex ".*\(\.py\|\.sh\)$"  #打印当前目录以.py或.sh结尾的文件名

find . -iregex ".*\(\.py\|\.sh\)$" #忽略大小写"

find . ! -name "*.txt" -print   #打印不以.txt结尾的文件名

find . -maxdepth 1 -name "f*" -print    #打印当前目录(1级目录)以f打头的文件名

find . -mindepth 2 -name "f*" -print   #打印深度距离当前目录至少两个子目录的文件名

find . -type d -print   #列出所有目录(d表示目录)
#f:普通文件,l:符号链接,c:字符设备,b:块设备,s:套接字,p:FIFO。

find . -type f -atime -7 -print #打印最近7天被访问过的文件
#-aitme:访问时间,-mtime:修改时间,-ctime:变化时间(元数据改变时间);单位:天
#-7:7天之内,7:恰好7天,+7:超过7天。
#-amin,-mmin,-cmin,以分钟为单位

find . -type f -newer file.txt  -print  #列出比file.txt修改时间更近的所有文件

find . -type f -size +2k    #列出大于2k的文件
#-2k:小于2k,2k:等于2k;
#b:块(512字节),c:字节,w:字(2字节),k:1024字节,M:1024k字节,G:1024M字节

find . -type f -name "*.swp" -delete    #删除以.swp结尾的文件

find . -type f -name "*.php" ! -perm 644 -print #打印权限不为644的php文件

find . -type f -user gycg -print    #打印gycg拥有的所有文件

find . -type f -user root -exec chown gycg {} \;    #将root拥有的文件所有者改为gycg

find . -type f -name "*.c" -exec cat {} \; >all_c_files.txt #将所有c文件拼接起来写入一个文件

find . -type f -mtime +10 -name "*.txt" -exec cp {} OLD \;  #将10天前的.txt文件复制到OLD目录中

find . -type f -name "*.txt" -exec printf "Text file: %s\n" {} \;

find /src \( -name ".git" -prune \) -o \(-type f -print \)  #打印不包括在.git中的所有文件名称

另外,匹配E-mail地址(name@host.toot),可以将其一般化为[a-z0-9]+@[a-z0-9]+.[a-z0-9]+。符号+指明在它之前的字符类中的字符可以出现一次或多次。

4 xargs

cat example.txt | xargs     #将多行输入转换成单行输出

cat example.txt | xargs -n 3    #多行输出,每行3个参数,每个参数是以空格分开的字符串

echo "splitXsplitXsplitXsplit" | xargs -d X #以X为定界符打印

echo "splitXsplitXsplitXsplit" | xargs -d X -n 2    #分两行输出

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

find . -type f -name "*.c" -print0 | xargs -0 wc -l #统计.c文件的行数

find files.txt | ( while read arg; do cat $arg; done ) #等同于cat files.txt | xargs -I {} cat {} 

5 tr

echo "HELLO WORLD" | tr 'A-Z' 'a-z' #转换为小写

echo 12345 | tr '0-9' '9876543210'  #加密
echo 87654 | tr '9876543210' '0-9'  #解密

echo "Hello 123 world 456" | tr -d '0-9'    #删除数字

echo hello 1 char 2  next 4 | tr -d -c '0-9 \n' #删除除了数字、空格、换行符之外的所有字符

echo "GNU is     not     UNIX. Recursive    right ?" | tr -s ' '    #-s压缩输入中重复的字符

tr '[:lower:]' '[:upper:]'  #小写转换为大写
#alnum,alpha,cntrl,digit,graph,lower,print(可打印字符),punct(标点),space,upper,xdigit(十六进制)

6 校验和与核实

md5sum filename > file_sum.md5  #将校验和存入文件中
md5sum -c file_sum.md5  #输出校验和是否匹配的消息

7 加密工具与散列

crypt PASSPHASE <input_file >encrypted_file #命令行也可以不输密码,会提示输入密码
crypt PASSPHASE -d <encrypted_file >output_file

gpg -c filename #加密
gpg filename.gpg    #解密

base64 filename > base64_file #或cat file | base64 > base64_file;加密
base64 -d base64_file > outputfile  #或cat base64_file | base64 -d > outputfile  #解密

8 排序

sort -r file.txt    #按逆序排序

sort -k 2 data.txt  #根据第二列进行排序

sort -rk 1 data.txt     #根据第一列逆序排列

sort -nk 2,3 data.txt   #根据2,3列进行排序,-n用于指明按照数字排序

sort -nk 1,1 data.txt   #用第一个字符作为键

sort -bd unsorted.txt   #-b用于忽略前导空白行,-d用于指明以字典序进行排序

uniq sorted.txt OR sort unsorted.txt | uniq

uniq -u sorted.txt OR sort unsorted.txt | uniq -u   #只显示唯一的行

sort unsorted.txt | uniq -c #统计各行在文件中出现的次数

sort unsorted.txt | uniq -d #找出重复的行

sort data.txt | uniq -s 2 -w 2  #忽略前两个字符(-s 2),最多比较两个字符(-w 2)

uniq -z file.txt    #生成包含0值字节终止符的输出

uniq -z file.txt | xargs -0 rm  #删除file.txt中指定的文件

9 临时文件

$ filename=`mktemp`
$ echo $filename   #创建一个临时文件,并打印出文件名

$ dirname=`mktemp -d`
$ echo $dirname        #创建一个临时目录,并打印出目录名

$ tempfile=`mktemp -u`
$ echo $tempfile   #文件名存储在tempfile中,但没有创建对应的文件

$ mktemp test.XXX  #根据模板创建文件名,至少有3个X

10 分割文件

split -b 10k data.file  #将data.file分割成多个文件,每个10k,默认命名x**,"*"为字母,如xaa,xab...

split -b 10k data.file -d -a 4  #-d指明以数字命名,-a 4指明数字长度为4,前缀为x

split -b 10k data.file -d -a 4 split_file   #设置前缀为split_file

split -l 10 data.file   #分割成多个文件,每个文件包含10行

csplit是split的一个变体,示例如下:

$ cat server.log
SERVER-1
[connection] 192.168.0.1 success
[connection] 192.168.0.2 failed
[disconnect] 192.168.0.3 pending
[connection] 192.168.0.4 success
SERVER-2
[connection] 192.168.0.1 failed
[connection] 192.168.0.2 failed
[disconnect] 192.168.0.3 success
[connection] 192.168.0.4 failed
SERVER-3
[connection] 192.168.0.1 pending
[connection] 192.168.0.2 pending
[disconnect] 192.168.0.3 pending
[connection] 192.168.0.4 failed

我们需要将这个日志文件分割成server1.log、server2.log和server3.log,这些文件的内容分别取自原文件中不同的SERVER部分。那么,可以使用下面的方法来实现:

$ 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。

因为分割后的第一个文件没有任何内容(匹配的单词就位于文件的第一行中),所以我们删 除了server00.log。

11 根据扩展名切分文件

$ URL="www.google.com"
$ echo ${URL%.*}   #移除.*所匹配的最右边的内容
www.google

$ echo ${URL%%.*}  #将从右边开始一直匹配到最左边的.*移除(贪婪操作符)
www

$ echo ${URL#*.}   #移除*.所匹配的最左边的内容
google.com

$ echo ${URL##*.}  #将从左边开始一直匹配到最右边的*.移除(贪婪操作符)
com

12 重命名

#!/bin/bash
#文件名:rename.sh
#用途:重命名.jpg和.png文件

count=1;
for img in `find . -iname '*.png' -o -iname '*.jpg' -type f -maxdepth 1`
do
    new==image-$count.${img##*.}

    echo "Renaming $img too $new"
    mv "$img" "$new"
    let count++
done

13 拼写检查和词典操作

#!/bin/bash
#文件名:checkword.sh
word=$1
grep "^$1$" /usr/share/dict/british-english -q
#^标记着单词的开始,$标记着单词的结束,-q禁止产生任何输出
if [ $? -eq 0 ]; then
    echo $word is a dictionary word;
else
    echo $word is not a dictionary word;
fi
#!/bin/bash
#文件名:aspellcheck.sh

word=$1

output=`echo \"$word\" | aspell list`
#当输入的不是一个词典单词,aspell list产生文本输出,反之不产生任何输出

if [ -z $output ]; then	#确认$output是否为空
    echo $word is a dictionary word;
else
    echo $word is not a dictionary word;
fi
$ look word filepath OR look "^word" filepath  #列出文件中以特定单词开头的所有单词,如果没有给出文件参数,则使用默认词典(/usr/share/dict/words)

14 交互输入自动化

#!/bin/bash
#文件名:interctive.sh
read -p "Enter number:" no;
read -p "Enter name:" name;
echo You have entered $no,$name;
$ echo -e "1\nhello\n" | bash interctive.sh
You have ectered 1,hello

$ echo -e "1\nhello\n" > input.data
$ bash interctive.sh < input.data
#!/usr/bin/expect
#文件名:automate_expect.sh
spawn bash interactive.sh   #指定自动化哪个命令
expect "Enter number:"      #等待的消息
send "1\n"          
#发送的消息
expect "Enter name:"
send "hello\n"
expect eof          #命令交互结束

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

#!/bin/bash
#文件名:generate_checksums.sh
PIDARRAY=()
for file in File1.iso File2.iso
do
    md5sum $file &
    PIDARRAY+=("$!")
done
wait ${PIDARRY[@]}
#多个md5sum命令是同时运行的,更快获得运行结果
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值