1、cat
[root@stone ~]# echo "aaa" | cat - num
aaa
1
2

#打印标准输入与文件内容
2、查找文件find
[root@stone ~]# ls num NUM
num  NUM
[root@stone ~]# find . -iname "num"
./NUM
./num

#-iname忽略字母大小写
[root@stone ~]# find . \( -name "num" -o -name "NUM" \)
./NUM
./num

#-o匹配多个条件,注意(和-之间有空格
[root@stone ~]# find . -path "*config*"
./file1/config.txt
./sysconfig/httpd.cfg

#-path匹配文件路径及文件

使用正则表达式搜素-regex
[root@stone ~]# find . -regex ".*\(\.tar\|\.rpm\)"
./awstats-7.1.1-1.noarch.rpm
./linux-2.6.32.60.tar
./rp-pppoe-3.5-32.1.src.rpm

#-regex匹配正则表达式,注意转义符的使用
[root@stone ~]# find . -name "*[0-9][0-9][0-9]*"
./a1234b

[root@stone ~]# find . -regex ".*[0-9][0-9][0-9].*"
./a1234b

#似乎不支持扩展的正则表达式,".*[0-9]{3}.*"不行。
#-regex与-iname最大的区别就在于 -regex是把find输出的整个结果(有别于绝对路径名)作为要匹配的对象, 而不仅仅是结果的最后一部分。
根据目录深度进行搜索
[root@stone ~]# find . -name hello
./hello
./file1/hello
[root@stone ~]# find . -maxdepth 1 -name hello
./hello
#maxdepth为1,表示当前目录
[root@stone ~]# find . -maxdepth 2 -name hello 
./hello
./file1/hello
#maxdepth为2,表示当前目录和二级目录,不深入到三级目录
[root@stone ~]# find . -mindepth 2 -name hello  
./file1/hello

#mindepth为2,表示从二级目录开始,忽略当前目录
根据文件类型搜素
find使用-type选项匹配文件类型,可匹配的文件类型如下:
文件类型
参数
普通文件
f
目录
d
符号链接
l
字符设备
c
块设备
b
套接字 s
fifo p
根据文件时间进行搜索
时间类型:
时间类型
参数
单位
访问时间
atime
修改时间
mtime
改变时间
ctime
访问时间
amin
修改时间
mtime
修改时间 ctime
时间选项,以-mtime为例:
   -mtime  n :n 为数字,意义为在 n 天之前的『一天之内』被更动过内容的文件;   -mtime +n :列出在 n 天之前(不含 n 天本身)被更动过内容的文件档名;   -mtime -n :列出在 n 天之内(不含 n 天本身)被更动过内容的文件档名。   -newer file :file 为一个存在的文件,列出比 file 还要新的文件档

建立三个文件,访问时间分别为今天19:00,昨天19:00,上前天的19:00,今天为5月8日,昨天为5月7日,上前天为5月5日

[root@stone ~]# touch timetest{1,2,3}
[root@stone ~]# touch -t "1305071900" timetest2 
[root@stone ~]# touch -t "1305051900" timetest3 

[root@stone ~]# stat time*
File: `timetest1'
Size: 0               Blocks: 8          IO Block: 4096   regular empty file
Device: 802h/2050d      Inode: 2553622     Links: 1
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2013-05-08 19:06:34.000000000 +0800
Modify: 2013-05-08 19:06:34.000000000 +0800
Change: 2013-05-08 19:06:34.000000000 +0800
File: `timetest2'
Size: 0               Blocks: 8          IO Block: 4096   regular empty file
Device: 802h/2050d      Inode: 2553623     Links: 1
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2013-05-07 19:00:00.000000000 +0800
Modify: 2013-05-07 19:00:00.000000000 +0800
Change: 2013-05-08 19:12:29.000000000 +0800
File: `timetest3'
Size: 0               Blocks: 8          IO Block: 4096   regular empty file
Device: 802h/2050d      Inode: 2553624     Links: 1
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2013-05-05 19:00:00.000000000 +0800
Modify: 2013-05-05 19:00:00.000000000 +0800
Change: 2013-05-08 19:12:37.000000000 +0800
[root@stone ~]# find . -atime 0 -name "timetest*"
./timetest1
#查找atime为当天的文件
[root@stone ~]# find . -atime 1 -name "timetest*" 
./timetest2
#查找atime为昨天的文件
[root@stone ~]# find . -atime +1 -name "timetest*"
./timetest3
#查找atime为昨天之前的文件,不包含昨天
[root@stone ~]# find . -atime -1 -name "timetest*" 
./timetest1

#查找atime为昨天之后的文件,不包含昨天,这儿实际上就是当天
[root@stone ~]# find . -newer timetest2 -name "timetest*"
./timetest1

#查找比timetest2这个文件的修改时间之后的文件,且文件开头为timetest
根据文件大小进行搜索-size
使用-size选项可以根据文件大小进行搜索,文件大小可用单位如下:
文件大小单位
含义
c
字节
W
字(2字节)
b
块(512字节)
K
Kb
M
Mb
G Gb
[root@stone ~]# mkdir file
[root@stone ~]# cd file/
[root@stone file]# dd if=/dev/zero of=f1 bs=1M count=1
1+0 records in
1+0 records out
1048576 bytes (1.0 MB) copied, 0.004076 seconds, 257 MB/s
[root@stone file]# dd if=/dev/zero of=f2 bs=1M count=2
2+0 records in
2+0 records out
2097152 bytes (2.1 MB) copied, 0.008129 seconds, 258 MB/s
[root@stone file]# dd if=/dev/zero of=f3 bs=1M count=3
3+0 records in
3+0 records out
3145728 bytes (3.1 MB) copied, 0.014168 seconds, 222 MB/s
[root@stone file]# ll -h
total 6.1M
-rw-r--r-- 1 root root 1.0M May  9 10:59 f1
-rw-r--r-- 1 root root 2.0M May  9 10:59 f2
-rw-r--r-- 1 root root 3.0M May  9 10:59 f3

#建立三个文件,分别为1M,2M,3M
[root@stone file]# find . -type f -size -2M 
./f1
#小于2M的文件
[root@stone file]# find . -type f -size 2M 
./f2
#等于2M的文件
[root@stone file]# find . -type f -size +2M
./f3

#大于2M的文件
删除匹配的文件-delete
[root@stone file]# find . -type f -size 2M -delete
[root@stone file]# ll -h
total 4.1M
-rw-r--r-- 1 root root 1.0M May  9 10:59 f1
-rw-r--r-- 1 root root 3.0M May  9 10:59 f3

根据文件权限进行搜索-perm
[root@stone file]# ll
total 28
-------r-- 1 root root 0 May  9 11:11 f1
----r----- 1 root root 0 May  9 11:11 f2
----r--r-- 1 root root 0 May  9 11:11 f3
-rw------- 1 root root 0 May  9 11:11 f4
-rw----r-- 1 root root 0 May  9 11:11 f5
-rw-r----- 1 root root 0 May  9 11:11 f6
-rw-r--r-- 1 root root 0 May  9 11:11 f7

#建立7个文件,权限分别为004,040,044,600,604,640,644
[root@stone file]# find . -type f -perm 044
./f3
#权限刚好为044的文件
[root@stone file]# find . -type f -perm +044
./f1
./f5
./f6
./f2
./f3
./f7
#权限包含044中任意一个的文件,f4的权限为600,一个也不包括
[root@stone file]# find . -type f -perm -044
./f3
./f7

#权限包括044全部的文件,f3为044,f7为644
根据用户名进行搜索-user
[root@stone file]#  ll f7
-rw-r--r-- 1 root root 0 May  9 11:11 f7

[root@stone file]# chown stone f7
[root@stone file]# ll f7
-rw-r--r-- 1 stone root 0 May  9 11:11 f7
[root@stone file]# find . -user stone
./f7

   -uid n :n 为数字,这个数字是使用者的帐号 ID,亦即 UID    -gid n :n 为数字,这个数字是群组名称的 ID,亦即 GID   -user name :name 为使用者帐号名称喔!例如 dmtsai    -group name:name 为群组名称喔,例如 users ;   -nouser    :寻找文件的拥有者不存在 /etc/passwd 的人!   -nogroup   :寻找文件的拥有群组不存在於 /etc/group 的文件!                当你自行安装软件时,很可能该软件的属性当中并没有文件拥有者,                这是可能的!在这个时候,就可以使用 -nouser 与 -nogroup 搜寻。

根据搜索结果执行额外命令-exec
[root@stone file]# ll f7
-rw-r--r-- 1 stone root 0 May  9 11:11 f7
[root@stone file]# find . -type f -user stone -exec chown root {} \;
[root@stone file]# ll f7
-rw-r--r-- 1 root root 0 May  9 11:11 f7

搜索时排除文件-prune
[root@stone file]# ls
f1  f2  f3  f4  f5  f6  f7

[root@stone file]# find . \( -name "f7" -prune \) -o \( -type f -print \)
./f1
./f5
./f6
./f2
./f4
./f3

3、将标准输入转换成命令参数:xargs
将多行输入转换成单行输出
[root@stone ~]# cat num
1
2
[root@stone ~]# cat num | xargs
1 2

将单行输入转换成多行输出,-n表示每行最大参数个数
[root@stone ~]# cat NUM 
1 2 3 4 5 6 7 8 9
[root@stone ~]# cat NUM | xargs -n 3
1 2 3
4 5 6
7 8 9

[root@stone ~]# cat NUM | xargs -n 4
1 2 3 4
5 6 7 8
9

默认情况下,xargs采用内部域分隔符(IFS)作为界定符,可以使用-d选项自定义
[root@stone ~]# cat NUM
12:34:567:89
[root@stone ~]# cat NUM | xargs -d ":" -n 1
12
34
567
89

参数传递
[root@stone ~]# cat bin/xargstest.sh 
#!/bin/bash
echo $*"#"
#创建xargstest.sh脚本
[root@stone ~]# cat num
1
2
3
4
5
#将脚本参数写入到num文本中
[root@stone ~]# cat num | xargs xargstest.sh
1 2 3 4 5#
#将num文本中的参数一次性传递给xargstest.sh脚本
[root@stone ~]# cat num | xargs -n 1 xargstest.sh
1#
2#
3#
4#
5#
#将num文本中的参数逐个传递给xargstest.sh脚本
[root@stone ~]# cat num | xargs -n 3 xargstest.sh
1 2 3#
4 5#

#将num文本中的参数三个一组传递给xargstest.sh脚本
[root@stone file]# ll
total 28
-------r-- 1 root root 0 May  9 11:11 f1
----r----- 1 root root 0 May  9 11:11 f2
----r--r-- 1 root root 0 May  9 11:11 f3
[root@stone file]# ls | xargs -t -i mv {} {}.bak
mv f1 f1.bak 
mv f2 f2.bak 
mv f3 f3.bak 
#-t 选项指示 xargs 先打印命令,然后再执行
#-i 选项告诉 xargs 用每项的名称替换 {}

[root@stone file]# ls
f1  f2  f3  f4  f_folder

[root@stone file]# cat f1
./f2
./f3
./f4
[root@stone file]# echo 1 2 > f2
[root@stone file]# echo 1 2 3 > f3
[root@stone file]# echo 1 2 3 4 > f4
[root@stone file]# cat f1 | xargs -i cat {}     
1 2
1 2 3
1 2 3 4
[root@stone file]# cat f{2,3,4}
1 2
1 2 3
1 2 3 4

[root@stone file]# ls
f1.bak  f2.bak  f3.bak  f4.bak  f5.bak  f6.bak  f7.bak
[root@stone file]# ls | xargs -t -p rm -rf   
rm -rf f1.bak f2.bak f3.bak f4.bak f5.bak f6.bak f7.bak ?...y
[root@stone file]# ls
#-p 选项为交互操作

[root@stone file]# touch f{1,2}
[root@stone file]# ls
f1  f2
[root@stone file]# file * | grep f3 | cut -d ":" -f1 | xargs -p rm -rf
rm -rf ?...

[root@stone file]# file * | grep f3 | cut -d ":" -f1 | xargs -p -r rm -rf
[root@stone file]# 

#-r 选项用在当没有要运行的内容,则退出命令
#深入理解xargs,看下面例子
[root@stone file]# ll
total 16
-rw-r--r-- 1 root root    0 May 10 17:37 f1
-rw-r--r-- 1 root root    0 May 10 17:38 f2
drwxr-xr-x 2 root root 4096 May 10 17:48 f_folder
[root@stone file]# ll f_folder/
total 0
[root@stone file]# ls | xargs cp
[root@stone file]# ll
total 16
-rw-r--r-- 1 root root    0 May 10 17:37 f1
-rw-r--r-- 1 root root    0 May 10 17:38 f2
drwxr-xr-x 2 root root 4096 May 10 17:50 f_folder
[root@stone file]# ll f_folder/
total 8
-rw-r--r-- 1 root root 0 May 10 17:50 f1

http://tagche.blog.51cto.com/649757/278539
http://blog.chinaunix.net/uid-1757778-id-2865835.html
find配合xargs使用
[root@stone file]# touch f{1,2}.txt
[root@stone file]# touch "aa f3.txt"
[root@stone file]# ls
aa f3.txt  f1  f1.txt  f2  f2.txt  f_folder

[root@stone file]# find . -maxdepth 1 -type f -name "*.txt" | od -a
0000000   .   /   f   2   .   t   x   t  nl   .   /   a   a  sp   f   3
0000020   .   t   x   t  nl   .   /   f   1   .   t   x   t  nl
0000036

[root@stone file]# find . -maxdepth 1 -type f -name "*.txt" | xargs rm -f
[root@stone file]# ls
aa f3.txt f1  f2  f_folder

#find搜索结果默认分隔符为IFS,故文件名中含有空格的话,就会出现问题
[root@stone file]# find . -maxdepth 1 -type f -name "*.txt" -print0  | od -a
0000000   .   /   f   2   .   t   x   t nul   .   /   a   a  sp   f   3
0000020   .   t   x   t nul   .   /   f   1   .   t   x   t nul
0000036

#使用-print0选项后,搜索结果使用"\0"(nul)作为分隔符
[root@stone file]# find . -maxdepth 1 -type f -name "*.txt" -print0  | xargs -0 rm -rf 
#xargs使用-0选项将"\0"(nul)作为分隔符
[root@stone file]# ls
f1  f2  f_folder

4、tr
替换
[root@stone file]# echo "hello wrold" | tr 'a-z' 'A-Z'
HELLO WROLD

[root@stone file]# echo "hello wrold" | tr [:lower:] [:upper:]
HELLO WROLD

[root@stone ~]# cat num
1
2
3
4
5

[root@stone ~]# cat num | echo $[$(tr '\n' '+')0] 
15

删除
[root@stone file]# echo "hello 123 world" | tr -d '0-9'
hello  world
[root@stone file]# echo "hello 123 world" | tr -d [:digit:]
hello  world

#-d选项表示删除
[root@stone file]# echo "hello 123 world" | tr -d -c '0-9 \n'
123
#-c选项表示保留后续字符集,删除其补集

压缩
[root@stone file]# echo "hello   123   world" | tr -s ' '    
hello 123 world

5、校验和
[root@stone ~]# md5sum num
a7b1ac3a2b072f71a8e0d463bf4eb822  num
#生成校验和
[root@stone ~]# md5sum num > num.md5
[root@stone ~]# cat num.md5 
a7b1ac3a2b072f71a8e0d463bf4eb822  num

[root@stone ~]# md5sum -c num.md5 
num: OK

#检查校验和
6、排序与筛选 sort&uniq
[root@stone ~]# cat sorttest 
1 apple 40
2 pear 20
3 orange 50
4 banana 10
[root@stone ~]# sort -nrk 1 sorttest 
4 banana 10
3 orange 50
2 pear 20
1 apple 40
[root@stone ~]# sort -k 2 sorttest 
1 apple 40
4 banana 10
3 orange 50
2 pear 20

#-n表示按数字排序
#-r表示逆序排序
#-k表示指定排序的序列
#-b表示忽略前面的空白字符
[root@stone ~]# cat NUM
1
1
2
2
3
[root@stone ~]# sort NUM | uniq
1
2
3
[root@stone ~]# sort NUM | uniq -u
3
[root@stone ~]# sort NUM | uniq -c
2 1
2 2
1 3

[root@stone ~]# sort NUM | uniq -d
1
2

#-u表示只显示出现过一次的行
#-c表示统计各行出现的次数
#-d显示出重复的行
[root@stone ~]# cat data.txt 
a:01:apple
d:03:pear
a:01:orange
a:01:banana
[root@stone ~]# sort data.txt | uniq -s 2 -w 2
a:01:apple
d:03:pear

#-s指定跳个前面n个字符
#-w指定用于比较的最大字符数
[root@stone ~]# ps -e -o user | sort | uniq -c | sort
168 root
1 dbus
1 nobody
1 ntp
1 quagga
1 ricci
1 rpc
1 smmsp
1 USER
1 xfs
2 avahi
4 haldaemon
8 apache
#统计各个用户的进程数
[root@stone ~]# ps -e -o state | sort | uniq -c | sort
189 S
1 R
1 Z

#统计各个状态的进程数
7、临时文件名和随机数
[root@stone ~]# temp_file="/tmp/var.$$"
[root@stone ~]# echo $temp_file
/tmp/var.9817
[root@stone ~]# temp_file="/tmp/var.$RANDOM"
[root@stone ~]# echo $temp_file             
/tmp/var.19100

8、分割文件和数据
9、根据扩展名切分文件名
[root@stone ~]# filename="file.tar.gz"
[root@stone ~]# echo ${filename%.*}
file.tar
#其中%.*表示删掉最右边的“."及后面的内容
[root@stone ~]# echo ${filename%%.*}
file
#其中%%.*表示删掉最左边的"."及后面的内容
[root@stone ~]# echo ${filename#*.} 
tar.gz
#其中#*.表示删掉最左边的"."及前面的内容
[root@stone ~]# echo ${filename##*.}
gz

#其中##*.表示删掉最右边的"."及前面的内容
10、批量重命名 rename

Linux的rename 命令有两个版本,一个是C语言版本的,一个是Perl语言版本的,早期的Linux发行版基本上使用的是C语言版本的,现在已经很难见到C语言版本的了,由于历史原因,在Perl语言大红大紫的时候,Linux的工具开发者们信仰Perl能取代C,所以大部分工具原来是C版本的都被Perl改写了,因为Perl版本的支持正则处理,所以功能更加强大,已经不再需要C语言版本的了。

1。如何区分系统里的rename命令是哪个版本的?

输入man rename 看到第一行是
RENAME(1) Linux Programmer’s Manual RENAME(1)
那么 这个就是C语言版本的。【我查看系统上应该就是C语言版本的】
而如果出现的是:
RENAME(1)              Perl Programmers Reference Guide              RENAME(1)
这个就是Perl版本的了!

两个版本的语法差异:
C语言的,按照man上面的注解,
rename的语法格式是:
rename fromtofile
这个命令有三个参数,分别是from : 修改什么名字,to:改成什么名字,file 需要修改的文件是哪些。
用法示例:
比如,有一批文件,都是以log开头的,log001.txt,  log002.txt ....... 一直到log100.txt
现在想要把这批文件的log全部替换为history
rename  log history log*【C的用法~】
这句命令的意思很明白了,把 以log开头的所有文件中的log字符替换为history
这样替换后的文件是:history001.txt,  history002.txt ..... 一直到history100.txt
rename C语言版本的另一个man示例是把后缀名批量修改,
比如我们要将所有jpeg的后缀名图片文件修改为jpg文件。
rename .jpeg.jpg*.jpeg
这样,所有以.jpeg扩展的后缀名全部被修改为.jpg
现在总结一下:

rename C语言版本所能实现的功能:批量修改文件名,结果是每个文件会被用相同的一个字符串替换掉!也就是说,无法实现诸如循环 然后按编号重命名!

2。Perl 版本的批量重命名,带有Perl的好处是,你可以使用正则表达式来完成很奇特的功能。

perl 版本的参数格式:
rename  perlexprfiles
注意,perl版本的rename只有两个参数,第一个参数为perl正则表达式,第二个参数为所要处理的文件
man rename的帮助示例:
1) 有一批文件,以.bak结尾,现在想把这些.bak 统统去掉。
rename     's/\.bak$//'       *.bak
这个命令很简单,因为我还没有系统学习过perl,我不知道perl里替换字符串是不是这么干的,但sed是这么干的,所以如果你有sed或者tr基础,很容易明白,这个替换和sed里的正则语法是一模一样的。
2) 把所有文件名内含有大小字母的,修改为小写字母。
rename      'y/A-Z/a-z/'      *
依然和sed的替换语法一样,不用多解释,如果看不懂的话,可以系统学习一下sed先。
还有几个比较实用的例子:

1) 批量去掉文件名里的空格
Linux文件名本来是不支持空格的,不知道什么时候允许了,当然,在命令行调用文件的时候,空格是很有问题滴,比如你 原来可以直接  mv  oldfile  newfile  但有空格就不行了 , 得加双引号:mv "oldfile"  "newfile" 或者用反斜杠转移  \[] ,这样还好,但如果你直接把含有空格的图片名引入Latex文档,Latex生成pdf的时候会直接打印出文件名,之前这个问题苦恼了我很久,我生成的pdf怎么老是出现文件名呢?后来才发现原来是文件名内含有空格的问题!windows系统下生成的文件名是天生含有空格的,虽然很讨厌,但有些惠普扫描仪生成的图片默认就加入了空格,没有办法,只好去掉他,在系统研究rename命令前,我是用mv 去除空格的。
网上流程的两个去空格的版本:

1) tr 版:
find . -type f -name "* *" -print |
while read name; do
na=$(echo $name | tr ' ' '_')
if [[ $name != $na ]]; then
mv "$name" $na
fi
done
这个版本以前我一直用的,不知道哪个网上搜刮来的,当时还没有系统的学习过tr/sed/awk命令。
注解一下,很好理解,find . type f -name "* *" -print 这一句是查找当前目录下所有类型为普通文件的 并且名字之中含有空格的文件,并打印出来,其实find默认就是打印的 这个-print 多余了,然后 通过管道传输给while 循环读取,文件名放到name 变量里,用tr 命令替换空格为下划线。 下面判断如果执行后的名称不相同,使用mv 命令重命名。但这个if判断可有可无,因为find已经查询了所有文件名中含有空格的,那么经过tr 命令后,$na变量肯定不等于$name 变量的。
所以这段代码可以简化:
find . -type f -name "* *" |
while read name; do
na=$(echo $name | tr ' ' '_')
mv "$name" "$na"
done
tr 可以看着是sed 的一个精简版本,tr 用下划线来替换空格。
还有一个 是sed 版本实现:
for f in *;do mv "$f" `echo "$f" | sed 's/[ ]\+/_/g' `; done
这里的sed表达式还可以这样写:
sed 's/[[:space:]]\+/_/g'
不过记住,sed里的出现一次或多次的加号是需要添加反斜杠的。即:\+,这样就可以了。
好了,这两种办法都太他妈罗嗦了,看看rename实现吧:
rename      's/[ ]+/_/g'       *
OK就这么简单。
方括号内的空格可以用[:space:]代替,
即可以写成's/[[:space:]]+/_/g'
这里注意,rename 采用的是标准perl正则语法,所以无须将加号转变为反斜杠加号
即+ 不能修改为\+,否则替换失败。

还有几个好玩的例子:
比如统一在文件头部添加上hello 
rename         's/^/hello/'       *
统一把.html扩展名修改为.htm
rename          's/.html$/.htm/'      *
统一在尾部追加.zip后缀:
rename          's/$/.zip/'      *
统一去掉.zip后缀:

rename          's/.zip$//'      *

规则化数字编号名,比如1.jpg, 2.jpg ..... 100.jpg , 现在要使文件名全部三位即1.jpg .... 001.jpg

运行两次命令:

rename           's/^/00/'          [0-9].jpg     # 这一步把1.jpg ..... 9.jpg 变幻为001.jpg .... 009.jpg

rename            's/^/0/'           [0-9][0-9].jpg   # 这一步把10.jpg ..... 99.jpg 变幻为010.jpg ..... 090.jpg

Ok ,rename就研究了这么多,暂时不知道如何在rename中引入动态变量,比如$i++

我测试过i=0;  rename -n "s/^.*$/$((++i))/"   * 执行后i被自增了1,并非想我想像中那样,可以在每操作一个文件自增一,猜想可能是因为rename批量实现的,导致++i只计算一次!

-n  用来测试rename过程,并不直接运行,可以查看测试效果后,然后再运行。
好了,再次说明一下,你在使用的时候一定要确认一下你语言的版本,我的是C语言版本~

RENAME(1)                  Linux Programmer’s Manual                 RENAME(1)

功能:

rename from to file...

用法:

For example, given the files foo1, ..., foo9, foo10, ..., foo278, the commands
              rename foo foo0 foo?
              rename foo foo0 foo??
       will turn them into foo001, ..., foo009, foo010, ..., foo278.

And
              rename .htm .html *.htm
       will fix the extension of your html files.

下面来看一个例子:

最后再来个实际应用当中的问题,先看下以下的图~

看到了吧,我们想把那个图片文件名中的ad字母换成big【注意:拷贝一份,不能直接替换】,那么想想该怎么做呢,对了,就是用rename~

cd /data/openshop_1028/IMG_SERVER/sources/goods/

find ./ -name "*_ad.jpg" -exec cp "{}" {}.1 \;

find ./ -name "*_ad.jpg.1" -exec renamead.jpg.1 big.jpg {} \;

假如要是能够直接替换的话,那就一条命令了:

cd /data/openshop_1028/IMG_SERVER/sources/goods/

find ./ -name "*_ad.jpg" -exec rename ad big {} \;

可以看以下的测试~


http://www.2cto.com/os/201201/117383.html

11、交互输入自动化read expect
[root@stone bin]# cat interactive.sh 
#!/bin/bash
#interactive.sh
read -p "enter number:" no
read -p "enter name:" name
echo you have entered $no, $name
[root@stone bin]# echo -e "1\nhello\n" | interactive.sh 
you have entered 1, hello

[root@stone ~]# echo -e "1\nhello\n" > input.data
[root@stone ~]# interactive.sh < input.data 
you have entered 1, hello

expect的简单用法
[root@stone bin]# cat automate_expect.sh 
#!/usr/bin/expect
#automate_expect.sh
spawn interactive.sh
expect "enter number:"
send "1\n"
expect "enter name:"
send "hello\n"
expect eof
[root@stone bin]# automate_expect.sh     
spawn interactive.sh
enter number:1
enter name:hello
you have entered 1, hello

#spawn指定需要自动化的脚本
#expect指定需要自动化的脚本里面等待输入前面的内容
#send指定自动输入的内容
#expect eof表示自动化交互结束
http://linux.chinaitlab.com/c/809655.html

一、概述

我们通过Shell可以实现简单的控制流功能,如:循环、判断等。但是对于需要交互的场合则必须通过人工来干预,有时候我们可能会需要实现和交互程序如telnet服务器等进行交互的功能。而Expect就使用来实现这种功能的工具。

  Expect是一个免费的编程工具语言,用来实现自动和交互式任务进行通信,而无需人的干预。Expect的作者Don Libes在1990年 开始编写Expect时对Expect做有如下定义:Expect是一个用来实现自动交互功能的软件套件 (Expect [is a] software suite for automating interactive tools)。使用它系统管理员 的可以创建脚本用来实现对命令或程序提供输入,而这些命令和程序是期望从终端(terminal)得到输入,一般来说这些输入都需要手工输入进行的。 Expect则可以根据程序的提示模拟标准输入提供给程序需要的输入来实现交互程序执行。甚至可以实现实现简单的BBS聊天机器人。 :)

  Expect是不断发展的,随着时间的流逝,其功能越来越强大,已经成为系统管理员的的一个强大助手。Expect需要Tcl编程语言的支持,要在系统上运行Expect必须首先安装Tcl。

  二、Expect工作原理

  从最简单的层次来说,Expect的工作方式象一个通用化的Chat脚本工具。Chat脚本最早用于UUCP网络内,以用来实现计算机之间需要建立连接时进行特定的登录会话的自动化。

  Chat脚本由一系列expect-send对组成:expect等待输出中输出特定的字符,通常是一个提示符,然后发送特定的响应。例如下面的 Chat脚本实现等待标准输出出现Login:字符串,然后发送somebody作为用户名;然后等待Password:提示符,并发出响应 sillyme。

  引用:Login: somebody Password: sillyme

  这个脚本用来实现一个登录过程,并用特定的用户名和密码实现登录。

  Expect最简单的脚本操作模式本质上和Chat脚本工作模式是一样的。

  例子:

  1、实现功能

  下面我们分析一个响应chsh命令的脚本。我们首先回顾一下这个交互命令的格式。假设我们要为用户chavez改变登录脚本,要求实现的命令交互过程如下:

  引用:# chsh chavez

  Changing the login shell for chavez

  Enter the new value, or press return for the default

  Login Shell [/bin/bash]: /bin/tcsh

  #

  可以看到该命令首先输出若干行提示信息并且提示输入用户新的登录shell。我们必须在提示信息后面输入用户的登录shell或者直接回车不修改登录shell。

  2、下面是一个能用来实现自动执行该命令的Expect脚本:

  #!/usr/bin/expect

  # Change a login shell to tcsh

  set user [lindex $argv 0]

  spawn chsh $user

  expect "]:"

  send "/bin/tcsh "

  expect eof

  exit

  这个简单的脚本可以解释很多Expect程序的特性。和其他脚本一样首行指定用来执行该脚本的命令程序,这里是/usr/bin/expect。程序第一行用来获得脚本的执行参数(其保存在数组$argv中,从0号开始是参数),并将其保存到变量user中。

  第二个参数使用Expect的spawn命令来启动脚本和命令的会话,这里启动的是chsh命令,实际上命令是以衍生子进程的方式来运行的。

  随后的expect和send命令用来实现交互过程。脚本首先等待输出中出现]:字符串,一旦在输出中出现chsh输出到的特征字符串(一般特征 字符串往往是等待输入的最后的提示符的特征信息)。对于其他不匹配的信息则会完全忽略。当脚本得到特征字符串时,expect将发送/bin/tcsh和 一个回车符给chsh命令。最后脚本等待命令退出(chsh结束),一旦接收到标识子进程已经结束的eof字符,expect脚本也就退出结束。

  3、决定如何响应

  管理员往往有这样的需求,希望根据当前的具体情况来以不同的方式对一个命令进行响应。我们可以通过后面的例子看到expect可以实现非常复杂的条件响应,而仅仅通过简单的修改预处理脚本就可以实现。下面的例子是一个更复杂的expect-send例子:

  expect -re "\[(.*)]:"

  if {$expect_out(1,string)!="/bin/tcsh"} {

  send "/bin/tcsh" }

  send " "

  expect eof

  在这个例子中,第一个expect命令现在使用了-re参数,这个参数表示指定的的字符串是一个正则表达式,而不是一个普通的字符串。对于上面这 个例子里是查找一个左方括号字符(其必须进行三次逃逸(escape),因此有三个符号,因为它对于expect和正则表达时来说都是特殊字符)后面跟有 零个或多个字符,最后是一个右方括号字符。这里.*表示表示一个或多个任意字符,将其存放在()中是因为将匹配结果存放在一个变量中以实现随后的对匹配结 果的访问。

  当发现一个匹配则检查包含在[]中的字符串,查看是否为/bin/tcsh。如果不是则发送/bin/tcsh给chsh命令作为输入,如果是则仅仅发送一个回车符。这个简单的针对具体情况发出不同相响应的小例子说明了expect的强大功能。

  在一个正则表达时中,可以在()中包含若干个部分并通过expect_out数组访问它们。各个部分在表达式中从左到右进行编码,从1开始(0包含有整个匹配输出)。()可能会出现嵌套情况,这这种情况下编码从最内层到最外层来进行的。

转载于:https://blog.51cto.com/stonebox/1339676

《Linux Shell脚本攻略》读书笔记第二章 命令之乐相关推荐

  1. Linux Shell脚本攻略 读书笔记

    内容目录: 嗨,Echo一下 给终端来点颜色 shell的控制结构 算术比较 目录操作 网站下载 tar 归档工具 rsync 备份系统快照 ftp自动传输 磁盘管理 故障排查 使用syslog记录日 ...

  2. linux cat 脚本,Linux Shell 脚本攻略 读书笔记 -- 201.cat的几种用法

    cat可以读取.显示和拼接文件内容 1. 打印单个文件: root@debian:/home/chicol/scripts# cat file.txt This is a line inside fi ...

  3. linux脚本结束语,读《Linux Shell脚本攻略》第9章笔记—结束语

    1. ps -e:(every),选项-ax(all)也可以生成同样的输出 -f:显示更多列 -o:指定想要显示的列(pcpu,pid,ppid,pmem,comm,cmd,user,nice,tim ...

  4. 【Linux Shell脚本攻略】第1章 小试牛刀

    第1章 小试牛刀 1.1 简介 1.2 在终端中显示输出 1.2.1 预备知识 1.2.2 实战演练 1.2.3 工作原理 1.2.4 补充内容 1.在echo中转义换行符 2.打印彩色输出 1.3 ...

  5. linux shell 脚本攻略学习11--mkdir和touch命令详解

    一.创建目录(mkdir命令详解) amosli@amosli-pc:~/learn$ mkdir dir amosli@amosli-pc:~/learn/dir$ mkdir folder amo ...

  6. LINUX SHELL脚本攻略笔记[速查]

    LINUX SHELL脚本攻略笔记[速查] Linux Shell脚本攻略笔记[速查] 资源 shell script run shell script echo printf 环境变量和变量 pgr ...

  7. linux shell 脚本 supress,《linux Shell 脚本攻略》进阶学习(第一部分)

    第二章命令之乐 cat 不仅可以读取文件并且连接数据,它还能从标准输入中进行读取 要从标准输入中读取,就要使用管道操作符 echo 'Text through stdin' | cat - file. ...

  8. 《Linux Shell脚本攻略》学习笔记-第一章

    1.1 简介 计算机可以从文本文件(称为shell脚本)中读取并执行命令. sehll脚本不仅节省了时间,而且清楚明白地表明了所执行的操作. bash shell变成了UNIX和Linux中既成事实的 ...

  9. linux shell脚本攻略_(python)Linux下shell脚本监控Tomcat的状态并实现自动启动步骤...

    今天为大家带来的内容是:(python)Linux下shell脚本监控Tomcat的状态并实现自动启动步骤 本文内容主要介绍了Linux下shell脚本监控Tomcat的状态并实现自动启动的步骤,文章 ...

  10. linux shell脚本攻略第3版_「技术干货」师傅说不会写shell脚本的网安不是一个好黑客,实战...

    shell脚本? 在说什么是shell脚本之前,先说说什么是shell. shell是外壳的意思,就是操作系统的外壳.我们可以通过shell命令来操作和控制操作系统,比如Linux中的Shell命令就 ...

最新文章

  1. 【Rsync项目实战一】备份全网服务器数据
  2. Arm 通过虚拟硬件与新的解决方案导向的产品 带动物联网经济转型
  3. PostgreSQL — 安装
  4. top与bottom、left与right的优先级
  5. cocos2dx scrollview和controlslider关联
  6. Hadoop源代码分析(MapReduce概论)
  7. 八种常见的 SQL 错误用法
  8. PP视频如何设置默认缓存个数
  9. 大数据统计学之概率论(三)
  10. 将流数据输出到Mysql中
  11. 不加载执行js_这些你不知道的前端隐藏加载执行JavaScript
  12. Android使用BaseAdapter绑定ListView实现不同item的TextView多种文字变色
  13. Python —— CPU vs. GPU
  14. 计算机网络复习题大全(各种题型)
  15. mysql连接数过多
  16. Tomcat配置文件server.xml(转)
  17. StringBuilder类的作用,以及与String类的相互转换
  18. 当你拥有足够的经验时,自然就会想到的东西---面向对象的设计原则!
  19. 用七牛生成音乐外链方法
  20. 手撸CAPL(二)——OSEK网络管理N个节点建环机制(包含节点建环/丢失/跳过等)代码自取

热门文章

  1. 提高网站性能之 —— 减少图片HTTP 请求的方案
  2. Ajax 登录控件(三)
  3. MAC安装软件 brew 问题记录
  4. 使用docker环境编译驱动
  5. 与程序员相关的CPU缓存知识
  6. CentOS 7下编译FreeSWITCH 1.6
  7. linux 设备驱动之8250串口驱动分析
  8. Anaconda 在线安装第三方库jieba
  9. python初级工程师面试题_Python工程师面试题
  10. arduino动态刷新显示_Arduino驱动TFT彩色触摸屏-有没有更好的方法?