Starter
特点
- 优点:
- 免费,开源
- 支持多线程,多用户
- 安全性好
- 对内存和文件管理优越
- linux 最小只需 4M => 嵌入式开发
- 缺点:
- 操作相对困难
历史
- 1960 麻省理工学院 30 个人同时使用
- 1965 mit,ge,bell 30 =>300 个人分时操作,multis计划【火星计划】
- 1969 火星计划失败,ken开发了一个file server system【文件系统】
- 1973 unix诞生 开源
- IBM: aix
- Sun: solaris
- Hp: hp-Unix
- 伯克利分校: bsd
- minix系统
- linus 芬兰 PC386 => 将minix移植到PC,1991=> 1994(1.0) linux[linus is not unix]
- RedHat红帽子公司
- s.u.s.e
- 红旗linux
- Ubuntu
运行级别
- 运行级别:
- 0 关机
- 1 单用户
- 2 多用户,无网络服务
- 3 多用户,有网络服务
- 4 系统未使用,保留给用户
- 5 图形界面
- 6 系统重启
- 常用运行级别 3/5
init[0123456]
启动- 修改运行级别
/etc/inittab
=>id:5:initdefault
修改这行中的数字 - 解决错误配置后无法启动:
- 在进入grub引导程序时,按e
- 选择第二行,输入e
- 在最后输入 1 回车,代表单用户级别( 因为单用户模式不读取
/etc/inittab
文件 ) - 按 b ,重新启动进入了单用户模式,再修改该配置文件
分区
- 基本分区(Primary Partion)
- 可以马上使用,单不能在分区
- 扩展分区(Extension Partion)
- 需进行二次分区后才可使用
- 即逻辑分区(Logical Partion),且无数量限制
- 硬盘
- 一块硬盘上: 基本分区(主分区)+扩展分区个数<=4
- 硬盘分两种:IDE/SCSI ("sdx~" / "hdx~")
sd
:SCSI硬盘(较好)hd
:IDE硬盘x
:盘号 (a 基本盘,b基本从属盘,c铺助盘,d铺助从属盘 )~
:分区 ( 1-4 主分区或扩展盘 ,5 开始为逻辑分区 )
- 相关命令:
mount [-参数] [设备名称] [挂载点]
umount [设备名称]
df
【查看磁盘使用情况】df -l
【查看某个目录在哪个分区】df -h
fdisk -l
【查看linux系统分区具体情况】
文件系统
级层式的树状目录结构,根目录 /
root
【存放root用户的相关文件】home
【存放普通用户的相关文件】bin
【存放常用命令】sbin
【存放需具有一定权限才可使用的命令】mnt
【默认挂载软驱,光驱的目录】etc
【存放系统配置与管理的相关文件】var
【存放经常变化的文件,具有变动性质的相关程序目录】boot
【存放系统启动时的引导文件】usr
【程序默认安装处】dev
【接口设备文件目录,如had表示硬盘】proc
【目前系统核心与程序执行的信息】
> ls -l
-rw-r--r--| 1 | tom | policeman | 11 | Dec 9 09:32 | myTest.java
-|rw-|r--|r--
文件类型及权限- 文件类型
-
代表普通文件d
代表文件夹 (其实也是个文件)l
代表链接
- 文件的所有者对该文件的权限
- 文件所在组的其他用户对该文件的权限
- 其他组的用户对该文件的权限
- 文件类型
1
- 若myTest.java是个文件,则为 1
- 若myTest.java是个文件夹,则表示次文件夹下有多少个文件
tom
文件所有者policeman
文件所在组11
文件大小Dec 9 09:32
最后修改日期myTest.java
文件名
文件使用:
组
groupadd policeman
【添加组】cat /etc/group | more
【查看所有linux中所有组信息】- eg:
policeman:x:503
- x :密码(加密了)
- 503 :代表policeman这个组的id
用户
useradd -g 组名 用户名
【创建用户,并将该用户分配到指定组中】passwd xxxxx
【设置密码】usermod -g 组名 用户名
【改变某个用户所在组(root才可操作)】userdel 用户名
【删除用户】userdel -r tom
【删除用户以及该用户主目录】eg:
> useradd -g policeman tom` > cat /ect/password | more tom:x:503:503::/home/tom:/bin/bash (用户名):(密码):(用户ID):(用户所在组ID)::(用户主目录):(此用户使用的Shell解析器)
文件owner
chown 用户名 文件名
【修改文件的所有者】chgrp 组名 文件名
【修改文件的所在组】 +ls -ahl
【查看文件的所有者】who am i
【查看当前用户】- eg:
> chown wang myTest.java > chown root ./tom > chown -R root ./tom 【改变tom这个目录及其下所有文件和目录的所有者为root】
文件访问权限(只有 root 和此文件的所有者可修改)
- 权限分三组:
- 文件所有者(o)
- 同组用户(g)
- 其余用户(a)
- 每组权限分为3位:
- r(read) 可读,用 4 表示
- w(write) 可写,用 2 表示
- x(execute) 可执行,用 1 表示
- 权限是相加的,例如:
- rwx是7
- rw是6
- 当对文件进行访问时,内核就检查进程关联的ID和该ID对应的权限位是否符合要求
- 操作与权限
操作 需要的权限 创建/删除/改名 文件 对父目录的w和x权限,以及所有祖先目录的x权限 修改文件权限 有效用户ID是文件所有者,或者拥有root权限 修改文件内容 对父目录的x权限,以及所有祖先目录的x权限 列出目录的文件列表 对父目录的rx权限,以及所有祖先目录的x权限 修改文件的所有者 拥有root权限 - 对于目录文件(文件夹)
- 读取权限:列出文件夹里文件列表的权限
- 写入权限:修改文件夹里的文件的名字的权限
- 执行权限:进入文件夹的权限
- eg:
> chmod 777 tom > chmod 770 tom > chmod u=rwx,g=rx,o=rx tom > chmod u-x,g+w tom > chmod a+r tom
- 注意:修改某文件夹的权限,不代表该文件夹下的文件的权限也跟着修改
- 权限分三组:
文件三个主要的变动时间:
- modification time (mtime):
- 当该文件的『内容数据』变更时,就会升级这个时间
- 内容数据指的是文件的内容,而不是文件的属性或权限
- status time (ctime):
- 当该文件的『状态 (status)』改变时,就会升级这个时间
- 举例来说,像是权限与属性被更改了,都会升级这个时间
- access time (atime):
- 当『该文件的内容被取用』时,就会升级这个读取时间 (access)
- 举例来说,我们使用 cat 去读取 /etc/man.config,就会升级该文件的 atime
- 示例:
> ls -l /etc/man.config -rw-r--r-- 1 root root 4617 Jan 6 2007 /etc/man.config > ls -l --time=atime /etc/man.config -rw-r--r-- 1 root root 4617 Sep 25 17:54 /etc/man.config > ls -l --time=ctime /etc/man.config -rw-r--r-- 1 root root 4617 Sep 4 18:03 /etc/man.config
- modification time (mtime):
修改文件时间或建置新档:
touch
共享
- windows <=> windows 使用网络邻居实现文件共享
- windows <=> linux 使用samba服务
管道
stdin(fd=0)
标准输入 (文件描述符为0)stdout(fd=1)
标准输出(文件描述符为1)stderr(fd=2)
标准错误输出 (文件描述符为2)>
将stdout定向输出到文件- 如果文件不存在,就创建文件;
- 如果文件存在,就将其清空;
- 相当于
1>
,不包括stderr >&
将stdout与stderr一起导向(command > stdout_file) > &stderr_file
把stderr和stdout分开导向2 > file.txt # 将文件句柄2(即stderr)重定向到文件file.txt中 2 > &1 # 将文件句柄2(即stderr)重定向到文件句柄1(即stdout)指向的文件中 test.sh > /tmp/test.log 2>&1
>>
将stdout追加到目标文件中- 如果文件不存在,就创建文件;
- 如果文件存在,则将新的内容追加到那个文件的末尾
|
管道,连结上个指令的标准输出,做为下个指令的标准输入cmd1 | cmd2
将cmd1 的 stdout 作为 cmd2 的 stdincmd1 | & cmd2
stderr合并到stdout, 然后管道到下一条命令
环境变量
# 查看环境变量
> env
# 查看某个环境变量
> echo 变量名
# 设置一个新变量
> export 变量名=变量值
# 在原变量值得基础上更新
> export 变量名=$变量名:xxx
# 清除某环境变量
> unset 变量名
例如:
export TEST="test" # 增加一个变量
env|grep TEST # 输出结果: TEST=test
unset TEST # 删除
env|grepTEST # 没有输出,证明变量TEST已不存在
/etc/profile
全局的环境变量文件,只要登陆系统的用户都会执行里面的ENV环境变量设置~/.profile
用户环境变量- 在用户主目录下
- 用户登陆时会执行此文件里的ENV环境变量设置
- 执行
. ~/.profile
立即生效
~/.kshrc
,~/.bshrc
,~/.cshrc
shell环境变量- 在用户主目录下
- 执行对应Shell下面的子shell时会执行此文件里的ENV环境变量设置
- 执行
. ~/.kshrc
/~/.bshrc
/~/.cshrc
立即生效
- 注意
- root用户的环境变量在
/etc/profile
下 - 从普通用户su到root时,环境变量设置可能不生效,需
su - root
- 处理直接执行配置文件外,也可使用
source
命令使配置生效
- root用户的环境变量在
vi 编辑器
vi Hello.java
i
【进入到插入模式insert】esc
键 【命令模式切换】- 输入冒号
:
wq
【保存退出】;q!
【退出不保存】
说明:
w
【写入保存】q
【退出,若内容修改,vi会报错】q!
【强制离开vi,并不保存文件】wq
【保存并退出vi】set nu
【在文件每行行处加入行号】set nonu
【取消行号】- 输入数字,再按
esc
键 【将光标移至该行行首】 /字符串
【查找字符串,按n键往下继续查找】?字符串
【查找字符串,按n键往上继续查找】
Shell
Shell名称 | 开发者 | 命令名称 |
---|---|---|
Bourne | S.R.Bourne | /bin/bash |
C | Bill Joy | /bin/csh |
Kom | David | /bin/ksh |
env
【显示当前操作系统的环境变量】chsh -s 新的shell
【修改当前使用的shell】- eg:
chsh -s /bin/csh
(生效需注销重新登录下)
- eg:
- 修改User的默认shell,有两种方式:
- 直接修改
/etc/passwd
文件(eg:/sbin/sh
=>/bin/bsh
) usermod -s /usr/bin/bash root
- 直接修改
- shell 解释为内核可执行的代码
- 命令(eg:cp,mkdir) <=> Shell <=>linux内核
常用命令
shutdown -h now 立即进行关机
shutdown -r now 现在重新启动计算机
reboot 现在重新启动计算机
startx 进入图形界面
su - 切换用户
logout 用户注销
tab 快捷键,自动补全
man 【相当于help】
dir
ls -a 【显示隐藏文件】
ls -l 【显示长列表格式】
cd 【改变目录】
pwd 【显示当前工作目录】
mkdir 【建立目录】
rmdir 【删除空目录】
touch 【建立空文件】
more 【分页显示,上一页ctrl+pageUp】
cp 【复制命令】
cp -r dir1 dir2 【递归复制命令】 eg: cp a.out /home/tom/
mv
rm
rm -rf 【删除所有内容,r表示递归,f表示强制】
ln 【建立符合连接】
ln -s 源目标
ln -s /etc/inittab inittab 【inittab 指向实际文件 /etc/inittab】
find 目录 -name aaa.java
find 目录 -amin -10 【 10分钟内存取的文件或目录 atime小时】
find 目录 -cmin -10 【 10分钟内更改的文件或目录 ctime小时 +表示前】
find 目录 -size +10k【 大小为10k的文件 】
shell history 查阅历史记录命令
history 5 【 显示最近使用的5个命令 】
!5 【 执行历史编号为5的命令 】
!ls 【 执行最后一次以ls开头的命令 】
> uname
SunOS
> uname -n
SZ1SA006
> hostname
SZ1SA006
> logname
cim1tdtp
> echo $LOGNAME
cim1tdtp
> whoami # 显示有效的当前用户
cim1tdtp
ls mv rm
ls
列出文件 / 文件夾 ls# 列出文件夾個數 ls -l | grep ^d | wc -l # 列出非文件夾個數 ls -l | grep -v ^d | wc -l # ls -F: 把文件按照类型归类(会在末尾加上/ *等符号标识) # grep /$ 挑出以/结尾的行 ;PS:/标识是目录 ls -F | grep /$
mv
移动/重命名mv MCK9[1-3]* 2009\. cat temp.txt | xargs -n1 -i mv {} 2011/
rm
刪除文件或目錄rm [-dfirv][--help][--version][文件或目录...]
-d
,--directory
删除目录。-f
,--force
强制删除文件或目录(即使原档案属性设为唯读,也直接删除,无需逐一确认)-i
,--interactive
删除前逐一询问确认。-r
,-R
,--recursive
递归处理,将指定目录下的所有文件及子目录一并处理。-v
,--verbose
显示指令执行过程。--help
在线帮助。--version
显示版本信息注意:删除目录必须加上参数
-r
,否则预设仅会删除文件#刪除文件 rm file #删除所有C语言程式档;删除前逐一询问确认 rm -i *.c #刪除文件夾 rm -r dir #批量刪除符合條件的文件 ls -d * | grep -v tar | xargs -n5 rm -r
tar,gzip,zip
ls -d * | xargs -n5 -i tar -cf {}.tar {}
ls -d * | xargs -n5 -i zip -r "{}.zip" {}
tar
- 参数:
-c
创建一个新归档-x
从归档中抽取文件-f
- 与
-c
选项一起使用时,创建的 tar 文件使用该选项指定的文件名; - 与
-x
选项一起使用时,则解除该选项指定的归档
- 与
-t
显示包括在 tar 文件中的文件列表-v
显示文件的归档进度-z
使用 gzip 来压缩 tar 文件-j
使用 bzip2 来压缩 tar 文件
- 包 (.tar文件)
- 打包:
tar cvf FileName.tar DirName
- 解包:
tar xvf FileName.tar
- 注:tar是打包,不是压缩!
- 打包:
- 压缩包 (.tar.Z)
- 解压:
tar Zxvf FileName.tar.Z
- 压缩:
tar Zcvf FileName.tar.Z DirName
- 解压:
示例:
# 将test文件夹打包为test.tar tar cvf test.tar test #將test文件夾打包為test.tar # 将test.tar包进行压缩为test.tar.Z文件 compress test.tar # 解压FileName.Z文件 uncompress FileName.Z # 一步到位,直接解压解包 uncompress < test.tar.Z | tar xf
- 参数:
gzip
- 参数:
-c
将输出写到标准输出上,并保留原有文件。-d
将压缩文件解压。-l
对每个压缩文件,显示下列字段:-r
递归式地查找指定目录并压缩其中的所有文件或者是解压缩。-t
测试,检查压缩文件是否完整。-v
对每一个压缩和解压的文件,显示文件名和压缩比。-num
用指定的数字num调整压缩的速度-1
或--fast
表示最快压缩方法(低压缩比)-9
或--best
表示最慢压缩方法(高压缩比)- 系统缺省值为6
示例:
# 压缩 gzip FileName # 解压缩 gzip -dv FileName
- 参数:
zip/unzip
zip [参数] [打包后的文件名] [打包的目录路径]
- 参数:
-a
将文件转成ASCII模式-F
尝试修复损坏的压缩文件-h
显示帮助界面-m
将文件压缩之后,删除源文件-n
特定字符串 不压缩具有特定字尾字符串的文件-o
将压缩文件内的所有文件的最新变动时间设为压缩时候的时间-q
安静模式,在压缩的时候不显示指令的执行过程-r
将指定的目录下的所有子目录以及文件一起处理-S
包含系统文件和隐含文件(S是大写)
示例
#压缩文件夹 zip -r test.zip test #解压 unzip test.zip
- 更多参考
ps,kill
查杀进程
ps -ef | grep nationz | grep "sh -c" | awk '{print $2}' | xargs -i kill -9 {}
ps -e -o pid -o comm
ps -ax -o pid -o comm | grep oic
ps -ax -o pid -o comm | grep oic
ps -e -o pid -o comm | grep oic | awk '{print $1}' | xargs -n2 -i kill -9 {}
kill -9 `ps -a -o pid -o comm | grep oic | awk '{print $1}'`
jobs,fg,bg
> sleep 15 &
[1] 2706
#列出当前活动作业
> jobs
[1] + Running sleep 15
# 显示作业号,PID
# jobs -l
[1] + 2706 Running sleep 15
> jobs
[1] Done sleep 15
> sleep 15 #按^Z停止sleep命令(sleep没有使用CPU但被挂起在后台)
^Z
Stopped (user)
> bg #使最后一个后台作业在后台开始执行
[1] + sleep 15 &
> jobs
[1] + Running sleep 15
> fg %1 #将编号为[1]的作业拿到前台
sleep 15
du,mount
du
查看文件或者目录大小-a
:显示全部目录和其次目录下的每个档案所占的磁盘空间-b
:大小用bytes来表示 (默认值为k bytes)-c
:最后再加上总计 (默认值)-s
:只显示各档案大小的总合 (summarize)-x
:只计算同属同一个档案系统的档案-L
:计算所有的档案大小- 常用:
du -sm
,du -sh
. 查询档案或目录的磁盘使用空间 fdisk
: 查看硬件分区的大小的- 一般使用:
fdisk -l
- 如果挂载了多块硬盘,每个硬盘有多个分区,就是用fdisk
- 一般使用:
- eg:
du -a du -h | awk '$1 ~ /G/' du -h | awk '$1 ~ /M/' du -ks /tmp df -k
装载 mount
# 装载 mount [-t vfstype] [-o options] device dir # 卸载 umount dir
-a
将/etc/fstab
中定义的所有档案系统挂上-f
伪装mount,作出检查设备和目录的样子,但并不真正挂载文件系统。-n
不把安装记录在/etc/mtab 文件中。-r
讲文件系统安装为只读。-v
详细显示安装信息。-w
将文件系统安装为可写,为命令默认情况。-t
指定设备的文件系统类型ext2
linux目前常用的文件系统msdos
MS-DOS的fat,就是fat16vfat
windows98常用的fat32nfs
网络文件系统iso9660
CD-ROM光盘标准文件系统ntfs
windows NT/2000/XP的文件系统auto
自动检测文件系统
-o
指定挂载文件系统时的选项,有些也可写到在/etc/fstab中defaults
使用所有选项的默认值(auto、nouser、rw、suid)auto
/noauto
允许/不允许以 –a选项进行安装dev
/nodev
对/不对文件系统上的特殊设备进行解释exec
/noexe
c 允许/不允许执行二进制代码suid
/nosuid
确认/不确认suid和sgid位user
/nouser
允许/不允许一般用户挂载codepage=XXX
代码页iocharset=XXX
字符集ro
以只读方式挂载rw
以读写方式挂载remount
重新安装已经安装了的文件系统
例如:
mount 10.7.33.25:/cim1_release /cim umount /cim
注意:
- 挂载点(dir):必须是一个已经存在的目录(目录可以不为空,但挂载后原内容将不可用,umount后恢复正常)
- 开机重启后自动挂载,需将挂载设置在
/etc/vfstab
文件中- 例如:将
10.7.33.25:/cim1_release/ - /cim nfs - yes bg,soft
添加到文件中
- 例如:将
更多参考
重执行命令
!
执行来自历史清单的一个命令!^
取得第1个变元!$
取得最后一个变元!*
取得所有变元!:2
取得第2个变元cat file1 file2 file3 ( 0 1 2 3 ) ls !:2 # ls file2 ls !^ # ls file1 ls !$ # ls file3 ls !* # ls file1 file2 file3 !!:p # ls file1 file2 file3 (打印但不执行历史清单中的最后一个命令,更新历史清单)
# 从历史清单中取得最后一个命令重新执行 !! # 重新执行历史清单中的第三个命令 !3 # 重新执行历史清单中以d开头的最后一个命令 !d
^
编辑前一个命令的一种快捷方法# 替换历史清单中最后一个命令中的字母 # 用一个t取得第一次出现的r ^r^t
cut
cut -b|c|f list [-d delim][-s][file ...]
从指定的范围中提取信息
提取形式:
-b
表示字节,即byte-c
表示字符,即character-f
表示字段,即field
提取范围(具体数字,从1开始计数):
m
第m个字节或字符或字段m-
从第m个字节或字符或字段到文件结束m-n
从第m个到第n个字节或字符或字段-n
从第1个到第n个字节或字符或字段
提取设置:
-d
用来定义分隔符(delimiter),默认为tab键-s
表示不包括哪些不含分隔符的行(有利于去掉注释和标题)
示例:
cut -c 1-5,10-14 test
cut -f 1,3 test
cut -d'|' -f2 1.test > 2.test
cut -d':' -f1,2 1.test > 2.test
cut -d':' -f1-4 /etc/passwd | head -10
cut -d':' -f 1-4 /etc/passwd | head -10
find
find path -option [ -print ] [ -exec|-ok command ] {} \;
path
: 查找目录~
表示$HOME
目录.
当前目录/
根目录
-option
:命令选项-name xxx
使用某种文件名模式来匹配文件find . -name "[A-Z]*" -print
-type b|d|c|p|l|f
查找某一类型的文件(块设备、目录、字符设备、管道、符号链接、普通文件)find /etc -type d -print
在/etc目录下查找所有的目录find . ! -type d -print
在当前目录下查找除目录以外的所有类型的文件find /etc -type l -print
在/etc目录下查找所有的符号链接文件
-size n[c]
按照文件长度来查找文件查- 这里所指的文件长度既可以用块(block)或字节(byte)来计量
- 在按照文件长度查找文件时,一般使用以字节表示文件长度
- 在查看文件系统的大小时,一般使用块来计量
find . -size +1000000c -print
在当前目录下查找文件长度大于1 M字节的文件find /home/apache -size 100c -print
在/home/apache目录下查找文件长度恰好为100字节的文件find . -size +10 -print
在当前目录下查找长度超过10块的文件(一块等于512字节)
-perm
按照文件执行权限查找-perm mode
:文件许可正好符合mode-perm +mode
:文件许可部分符合mode-perm -mode
: 文件许可完全符合mode- eg:
find . -perm 755 -print
-prune
指出需要忽略的目录- 如果同时使用
-depth
选项,那么-prune
将被忽略 find [-path ..] [expression]
(表达式按顺序求值)- eg:在
/apps
目录下查找不在bin
子目录之内的所有文件 find /apps -path "/apps/bin" -prune -o -print
与find /apps -path "/apps/bin" -a -prune -o -print
等同-a
和-o
都是短路求值,与 shell 的&&
(and)和||
(or)类似- 伪码相当于:
if -path "/usr/sam" then -prune else -print
find /usr/sam \(-path /usr/sam/dir1 -o -path /usr/sam/file1 \) -prune -o -name "temp" -print
避开多个文件夹,-name
在-o
之后
- 如果同时使用
-depth
首先匹配所有的文件然后再进入子目录中查找- 默认find将遍历所有子目录
- 如果只想搜索当前目录,可以添加
-maxdepth 0
表示只检验命令行给定的文件
-follow
跟踪符号链接所指向的文件-mount
查文件时不跨越文件系统mount点find . -name "*.XC" -mount -print
从当前目录开始查找位于本文件系统中文件名以XC结尾的文件
-newer
查找比某个文件新或旧的文件-newer f1 !f2
#查更改时间比f1新但比f2旧的文件
-ctime
,-atime
,-mtime
按文件 创建|访问|更改 时间来查找文件-n
指n天以内+n
指n天以前
-user xxx
,nouser
按照文件属主来查找文件find ~ -user sam -print
find /etc -user uucp -print
在/etc目录下查找文件属主为uucp的文件find /home -nouser -print
查找属主帐户已经被删除的文件(即找到那些属主在/etc/passwd文件中没有有效帐户的文件)
-group xxx
,nogroup
按文件所属于的用户组查找文件find /apps -group gem -print
find / -nogroup -print
查找无有效所属组的文件(即该文件所属的组在/etc/groups中不存在)
-print
: 将匹配的文件输出到标准输出- 只会输出从当前路径起的相对路径及文件名
-exec
,-ok
: 执行shell命令,参数为匹配的文件-exec command {} \;
:将查到的文件执行command操作-ok command {} \;
: 与-exec
一样,不过执行操作前会询问- 注意:必须要使用
-print
选项;{}
和\
间有空格 find logs -type f -mtime +5 -exec rm { } \;
在/logs目录中查找更改时间在5日以前的文件并删除它们
注意:
使用-exec
时,find命令将所有匹配到的文件一起传递给exec执行
可能会出现溢出错误(参数列太长”,“参数列溢出”,...)
可能会出现进程过多,系统性能下降的问题(有些系统中会为处理每一个匹配到的文件而发起一个相应的进程)
建议使用xargs
分批获取和传入参数,且只有一个进程,eg:
# 查找系统中的每一个普通文件,然后使用xargs命令来测试它们分别属于哪类文件
> find . -type f -print | xargs file
./.kde/Autostart/Autorun.desktop: UTF-8 Unicode English text
./.kde/Autostart/.directory: ISO-8859 text\
......
使用示例:
# 当前目录下查找所有用户具有读、写和执行权限的文件,并收回相应的写权限
find . -perm -7 -print | xargs chmod o-w
# 用grep命令在所有的普通文件中搜索hostname这个词
find . -type f -print | xargs grep "hostname"
# 查找系统中所有文件长度为0的普通文件,并列出它们的完整路径
find / -type f -size 0 -exec ls -l { } \;
# 让当前目录中文件属主具有读、写权限,并且文件所属组的用户和其他用户具有读权限的文件
find . -type f -perm 644 -exec ls -l { } \;
# 查找/var/logs目录中更改时间在7日以前的普通文件,并在删除之前询问它们
find /var/logs -type f -mtime +7 -ok rm { } \;
#查找系统中所有属于root组的文件
find . -group root -exec ls -l { } \;
# 删除当目录中访问时间在7日以来、含有数字后缀的admin.log文件
find . -name "admin.log[0-9][0-9][0-9]" -atime -7 -ok rm { } \;
#查找当前文件系统中的所有目录并排序
find . -type d | sort
# 从当前目录开始,向下扫描查找类型是普通文件的所有.html文件
find -name "*.html" -type f
# 返回文件权限和时间信息(-iname:表示区分大小写)
find -user chen -iname "*.html" -ls
# 在/logos 下查找5天内修改的普通日志文件并删除
find /logos -type f -mtime -5 -exec rm {} /;
#查找2004-11-30 16:36:37时更改过的文件
find ./ -name "*php" | ls -l --full-time $A 2>/dev/null | grep "2004-11-30 16:36:37"
# 文件查找
find . -ctime +365 -type d -exec ls -ld {} \; >test.txt
find . -ctime +365 -type d -exec ls -ld {} \; >test.txt
find . -name "*.txt" -print
find . -name *.* -ctime -365 -type d -exec mv {} temp/ \;
find . -name *.* -ctime -365 -type d -exec mv {} temp/ \;
find . -name *.gz -ctime -365 -exec ls -l {} \
find . -type d -exec ls -ld {} \; >test.txt
find . -type d -exec ls -ld {} \; >test.txt
xargs
xargs [-0epns] [ command [initial-arguments] ]
build and execute command lines from standard input
- 字面意义上:x 是乘号,args 是 arguments (参数) ,则xargs的意思就是产生某个指令的参数
- xargs 可读入 stdin 的资料,以空白字元或断行字元作分辨,将 stdin 的资料分隔成 args
- 使用其他某个命令并将前一个命令的输出作为参数
- 将参数列表转换成小块分段传递给其他命令,以避免参数列表过长的问题
- xargs本身虽然没有多大用处,但在与其他命令相结合时,它的功能非常强大
- 注意:因为是以空白字元作为分隔,所以如果有一些档名或者是其他意义的名词内含有空白字元的时候,xargs 可能会误判
參數:
-i
选项告诉xargs用每项的名称替换{}
find ./ -type f -print | xargs -i mv -f {} ./newdir
-t
选项指示xargs先打印要运行的命令,然后再执行ls | xargs -t -i mv {} {}.bak cat listFile | xargs -t -i ls ~/re-extract/"{}"
-0
将输入的特殊字元(例如,
,\
, 空白键等)还原成一般字元,可用于正确地处理了新行和空格# 查找tmp目录下以core命名的文件,然后删除 # 如果文件名字包含新行或者空格的话,这条命令将会被错误操作 > find /tmp -name core -type f -print | xargs /bin/rm -f # 这条命令就正确地处理了新行和空格,有可能带来的错误 > find /tmp -name core -type f -print0 | xargs -0 /bin/rm -f
-p
它使操作具有可交互性,在执行每个指令的 argument 时,都会询问使用者的意思:# xarg要求在运行每个命令之前进行确认,按下"y",则执行 file * | grep ASCII | cut -d":" -f1 | xargs -p vi vi alert_DBA102.log dba102_cjq0_14493.trc dba102_mmnl_14497.trc dba102_reco_14491.trc dba102_rvwr_14518.trc ?...
-r
如果没有要运行的内容,该命令退出:file * | grep SSSSSS | cut -d":" -f1 | xargs -t -r wc -l $
-n
指定每次从输入源中取几行数据(限制单个命令行的参数个数):# 限制每个命令行仅使用两个参数 file * | grep ASCII | cut -d":" -f1 | xargs -t -n2 ls -ltr
-e
: EOF (end of file) 后面可接一个字串,代表结束标识(当 xargs 分析到这个字串时,就会停止继续工作)# 当分析到 lp 就结束这串指令 (注意 -e'lp' 是连在一起的,中间没有空白键) cut -d':' -f1 < /etc/passwd | xargs -e'lp' finger
-s
: 每次的输出的最大bytes
示例:
将
/etc/passwd
的第一栏取出,仅取三行,使用finger
这个指令秀出每个帐号内容- 由 finger account 可以取得该帐号的相关说明内容
- 利用 cut 取出帐号名称
- 用 head 取出三个帐号
由 xargs 将三个帐号的名称变成 finger 后面需要的参数
> cut -d ':' -f1 < /etc/passwd | head -n 3 | xargs finger Login name: root In real life: Super-User Directory: / Shell: /sbin/sh Last login Thu Jan 5 08:44 on pts/2 from 10.7.82.110 New mail received Sun Feb 5 14:00:26 2012; unread since Thu Feb 21 11:53:16 2008 No Plan. Login name: daemon Directory: / Never logged in. No unread mail No Plan. Login name: bin Directory: /usr/bin Never logged in. No unread mail No Plan.
删除数量比较多的文件
ls
输出所有的文件名(用空格分割)xargs
将ls的输出,每20个为一组(以空格为分隔符),作为rm -rf
的参数- 即将所有文件名20个为一组,由
rm -rf
删除,这样就不会超过命令行的长度了ls | xargs -n 20 rm -fr
迁移文件
cat temp.txt | xargs -n1 -i mv {} bak/ ls *100[9]* | xargs -t -i mv {} "/db/data/autoftp/sent/tsmc/stdfbak/" ls *100[7]*.gz | xargs -t -i -n1 mv {} "/db/data/autoftp/sent/tsmc/stdfbak/"{}
xargs
与grep
使用比较XXX | grep –i ‘hello’
- grep通过管道读取XXX的输出结果,并在该结果中搜索hello
XXX | xargs grep –i ‘hello’
- xargs通过管道读取XXX的输出结果,并将该结果作为grep的最后的FILE参数
grep –i ‘hello’
组合成完整的命令(如grep –i ‘hello’ stdio.h stdlib.h
)后,执行- 例如:
find . -name "*.foo" | xargs grep bar
大体等价于grep bar `find . -name "*.foo"`
- 两者对于管道的输出作不同的处理:
- 前者是grep直接从stdin中读取管道数据,并搜索。
- 后者是xargs直接从stdin中读取管道数据,并和
grep –i ‘hello’
组合,然后调用exec
执行该命令
awk
文本分析工具
nawk '/pattern/{action}' filename
cmd | nawk '/pattern/{action}' filename
- 把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行各种分析处理
pattern
表示 AWK 在数据中查找的内容,可使用正则表达式(正则表达式需用斜杠括起来)action
是在找到匹配内容时所执行的一系列命令-F
域分隔符,默认是空格内置变量:
ARGC
命令行参数个数ARGV
命令行参数数组ENVIRON
支持队列中系统环境变量的使用FILENAME
awk浏览的文件名FNR
浏览文件的记录数NF
当前记录中的字段数(记录域个数)NR
当前已读的记录数OFS
设置输出域分隔符,默认为空格FS
设置输入域分隔符,默认为空格,/,跳個符(等价于命令行-F
选项)ORS
输入记录分隔符RS
输出记录分隔符OFMT
控制打印數,默認為%.6g
(打印精確到小數點后6位)$0
整條記錄$1
表示当前行的第一个域
內置函数
- sub,gsub,length,match,split
- 算数运算函数:int,log,sin,sqrt,rand,srand
- 打印输出函数:print,printf
print \b,\f,\n,\r,\t,\c
printf %c,%d,%e,%f,%o,%s,%x
格式化特制的輸出- eg:
{print "\t\tHave a nice day," $1,$2 "\!"} {printf "%The name is: -15s ;ID is %8d\n",$1,$3}
- 用户自定义函数
示例:
# pattern nawk '/Mary/' file1.txt nawk '$1 ~ /[Bb]ill/' file2.txt # action:print nawk '{print $1,$2}' file1.txt nawk '/^[A-Z][a-z]+/{print "Hello "$0}' file1.txt # -F nawk -F: '/Tom Jones/{print $0,NF}' file1.txt nawk -F'[ :\t]' '/Tom Jones/{print $0,NF}' file1.txt # argv nawk 'BEGIN{print substr(ARGV[1],11,1)}' $argv[2] # cmd | awk ps -ef | grep ftp | grep Feb | awk '{print $11}' | uniq | more # 批量重命名 ls *.tar | awk -F"." '{print $1"."$2"."$3"."$4,$1"."$2"."$3".1"}'| xargs -n2 mv ls * | awk -F"." '{print $1"."$2"."$3,$1"."$2}' | xargs -n2 mv ls * | awk -F"." '{print $1"."$2"."$3,$1"."$2"."$3".1"}' | xargs -n2 mv
示例:
解析文档(关联数组,统计,printf,算数运算,sort应用)
#! /bin/csh echo Begin set resultFile = myResult.txt # get head #head -8 Testdata.log | awk -F, '{print $1":"$2}' > $resultFile awk -F, 'NR==1 {print $1":"$2 }' Testdata.log > $resultFile nawk -F, 'NR==2 {print $1":"tolower($2) }' Testdata.log >> $resultFile awk -F, 'NR==3,NR==8 {print $1":"$2 }' Testdata.log >> $resultFile echo StartDate:`awk -F, 'NR==9{print $2}' Testdata.log | cut -c1-8` >> $resultFile echo StartTime:`awk -F, 'NR==9{print $2}' Testdata.log | cut -c9-14` >> $resultFile # get Passdie,Grossdie,Yeild awk -F, 'NR>10 { grossdie++;if($5=="P") count++}END {printf("Passdie:%d\nGrossdie:%d\nYield:%.2f\n\n",count,grossdie,count/grossdie*100)} ' Testdata.log >>$resultFile # get x,y,bin,site,status,[ bin Summary ] awk -F, 'NR>10{print "x="$1,"y="$2,"bin="$3,"site="$4,"status="$5}' Testdata.log >> $resultFile echo >> $resultFile echo "[bin summary]" >> $resultFile echo >> $resultFile awk -F, 'NR>10{count[$3]++;}END{for(i in count){print "bin"i":"count[i] | "sort -t: +0.3n"}}' Testdata.log >> $resultFile echo End\! exit
awk -F, 'NR>10{count[$3]++; print "x="$1,"y="$2,"bin="$3,"site="$4,"status="$5 }END{ printf("\n[bin summary]\n"); for(i in count){print "bin"i":"count[i] | "sort -t: +0.3n" };Close "sort -t: +0.3n"}' Testdata.log
根据传入参数去除重复行
输入源
> cat uniqueTest.txt 222|15|2401668|3273877|4114|1| 222|15|2401444|3273847|3274|1| 222|15|2401444|32722200|4124|1| 222|15|2401474|32253847|7419|1|
去除重复的行
# 根据第三列判断重复行 > awk -F"|" '{a[$3]=$0}END{for (i in a) print a[i]}' uniqueTest.txt 222|15|2401444|32722200|4124|1| 222|15|2401474|32253847|7419|1| 222|15|2401668|3273877|4114|1| # 根据第三第四列组合判断重复行 > awk -F"|" '{a[$3$4]=$0;b[$3$4]=NR}END{for (i in a) print b[i] " " a[i]}' uniqueTest.txt 3 222|15|2401444|32722200|4124|1| 2 222|15|2401444|3273847|3274|1| 4 222|15|2401474|32253847|7419|1| 1 222|15|2401668|3273877|4114|1|
- 传入参数
> set xField = 3 > set yField=4 > awk -F"|" '{a[$x$y]=$0;b[$x$y]=NR}END{for (i in a) print b[i] " " a[i]}' x="$xField" y="$yField" uniqueTest.txt
BEGIN/END
- 测试数据:
docker@default:~$ cat /etc/passwd root:x:0:0:root:/root:/bin/sh lp:x:7:7:lp:/var/spool/lpd:/bin/sh nobody:x:65534:65534:nobody:/nonexistent:/bin/false tc:x:1001:50:Linux User,,,:/home/tc:/bin/sh dockremap:x:100:101:Linux User,,,:/home/dockremap:/bin/false docker:x:1000:50:Linux User,,,:/home/docker:/bin/sh
- 显示
/etc/passwd
的账户name和账户对应的shell, 第一行添加列名"name,shell", 最后一行添加"blue,/bin/nosh"docker@default:~$ cat /etc/passwd |awk -F ':' 'BEGIN {print "name,shell"} {print $1","$7} END {print "blue,/bin/nosh"}' name,shell root,/bin/sh lp,/bin/sh nobody,/bin/false tc,/bin/sh dockremap,/bin/false docker,/bin/sh blue,/bin/nosh
- 显示文件名filename,行号linenumber,列数columnes,每行内容linecontent
# 使用printf替代print,更加简洁 # eg:awk -F ':' '{printf("filename:%10s,linenumber:%s,columns:%s,linecontent:%s\n",FILENAME,NR,NF,$0)}' /etc/passwd docker@default:~$ awk -F ':' '{print "filename:" FILENAME ",linenumber:" NR ",columns:" NF ",linecontent:"$0}' /etc/passwd filename:/etc/passwd,linenumber:1,columns:7,linecontent:root:x:0:0:root:/root:/bin/sh filename:/etc/passwd,linenumber:2,columns:7,linecontent:lp:x:7:7:lp:/var/spool/lpd:/bin/sh filename:/etc/passwd,linenumber:3,columns:7,linecontent:nobody:x:65534:65534:nobody:/nonexistent:/bin/false filename:/etc/passwd,linenumber:4,columns:7,linecontent:tc:x:1001:50:Linux User,,,:/home/tc:/bin/sh filename:/etc/passwd,linenumber:5,columns:7,linecontent:dockremap:x:100:101:Linux User,,,:/home/dockremap:/bin/false filename:/etc/passwd,linenumber:6,columns:7,linecontent:docker:x:1000:50:Linux User,,,:/home/docker:/bin/sh
可自定义变量,
{action}
可以有多个语句,以;
号隔开docker@default:~$ awk '{count++;print $0;} END{print "user count is ", count}' /etc/passwd root:x:0:0:root:/root:/bin/sh lp:x:7:7:lp:/var/spool/lpd:/bin/sh nobody:x:65534:65534:nobody:/nonexistent:/bin/false tc:x:1001:50:Linux User,,,:/home/tc:/bin/sh dockremap:x:100:101:Linux User,,,:/home/dockremap:/bin/false docker:x:1000:50:Linux User,,,:/home/docker:/bin/sh user count is 6 docker@default:~$ awk 'BEGIN {count=0;print "[start]user count is ", count} {count=count+1;print $0;} END{print "[end]user count is ", count}' /etc/passwd [start]user count is 0 root:x:0:0:root:/root:/bin/sh lp:x:7:7:lp:/var/spool/lpd:/bin/sh nobody:x:65534:65534:nobody:/nonexistent:/bin/false tc:x:1001:50:Linux User,,,:/home/tc:/bin/sh dockremap:x:100:101:Linux User,,,:/home/dockremap:/bin/false docker:x:1000:50:Linux User,,,:/home/docker:/bin/sh [end]user count is 6
- 收集信息存储到数组, 下标可以是数字和字母( 存储在内部的一张hash表里,即非顺序存储)
docker@default:~$ awk -F ':' 'BEGIN {count=0;} {name[count] = $1;count++;}; END{for (i = 0; i < NR; i++) print i, name[i]}' /etc/passwd 0 root 1 lp 2 nobody 3 tc 4 dockremap 5 docker
- 测试数据:
sed
sed [-nefri] [command]
说明:
Options:
[-nefri]
-n
: 使用安静(silent)模式。在一般sed的用法中,所有来自STDIN
的资料一般都会被列出到屏幕上。加上-n
后,则只有经过sed 特殊处理的那一行(或者动作)才会被列出来-e
∶多点编辑,等价于--expression
# 同 /sbin/ifconfig | grep 'inet ' | sed 's/inet//g' | sed 's/netmask.*//g' > /sbin/ifconfig | grep 'inet ' | sed -e 's/inet //g' -e 's/ netmask.*//g' 172.17.0.2 127.0.0.1
-f
∶指定sed脚本的文件名。 直接将sed的动作写在一个档案内,-f filename
则可以执行filename内的sed动作-r
∶sed 的动作支援的是延伸型正则表达式的语法。(预设是基础正则表达式语法)-i
∶直接修改读取的文件内容,而不是由屏幕输出# 直接在文件最后一行加入“This is a test” > cat 1.txt AAA BBB CCC > sed -i '$a This is a test' 1.txt > cat 1.txt AAA BBB CCC This is a test
Command:
:[n1[,n2]]function
a\
∶ 新增。后面可接字串,在当前行下面插入> nl /etc/passwd | sed '2a drink tea' 1 root:x:0:0:root:/root:/bin/bash 2 bin:x:1:1:bin:/bin:/sbin/nologin drink tea 3 daemon:x:2:2:daemon:/sbin:/sbin/nologin 4 adm:x:3:4:adm:/var/adm:/sbin/nologin
# 加入两行,中间用‘\’换行输入或使用‘\n’来进行新行的添加: > nl /etc/passwd | sed '2a Drink tea or ......\ drink beer ?' 1 root:x:0:0:root:/root:/bin/bash 2 bin:x:1:1:bin:/bin:/sbin/nologin Drink tea or ...... drink beer ? 3 daemon:x:2:2:daemon:/sbin:/sbin/nologin 4 adm:x:3:4:adm:/var/adm:/sbin/nologin
i\
∶ 插入。后面可以接字串,在当前行上面插入文本> nl /etc/passwd | sed '2i drink tea' 1 root:x:0:0:root:/root:/bin/bash drink tea 2 bin:x:1:1:bin:/bin:/sbin/nologin 3 daemon:x:2:2:daemon:/sbin:/sbin/nologin 4 adm:x:3:4:adm:/var/adm:/sbin/nologin
c\
∶替换行。后面可以接字串,把选定的行改为新的文本# 将第2-4行的内容取代成为"No 2-4 number" > nl /etc/passwd | sed '2,4c No 2-4 number' 1 root:x:0:0:root:/root:/bin/bash No 2-4 number 5 lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin 6 sync:x:5:0:sync:/sbin:/bin/sync
s
∶ 替换行中字符。可以直接进行替换指定字符。通常这个s
的动作可以搭配正则表达式。例如1,20s/old/new/g
> /sbin/ifconfig | grep 'inet ' inet 172.17.0.2 netmask 255.255.0.0 broadcast 0.0.0.0 inet 127.0.0.1 netmask 255.0.0.0 > /sbin/ifconfig | grep 'inet ' | sed 's/inet //g' 172.17.0.2 netmask 255.255.0.0 broadcast 0.0.0.0 127.0.0.1 netmask 255.0.0.0 > /sbin/ifconfig | grep 'inet ' | sed 's/inet//g' | sed 's/netmask.*//g' 172.17.0.2 127.0.0.1
g
: 全局搜索。整行匹配的都替换,没有g
则只替换一行中第一个匹配的内容,当需要从第N处匹配开始替换时,可以使用/Ng
sed 's/book/books/g' file sed 's/book/books/2g' file
y
:把一个字符翻译为另外的字符(不能用正则表达式)# 把1~10行内所有abcde转变为大写 sed '1,10y/abcde/ABCDE/' file
d
:删除。后面通常不接任何内容sed '2d' datafile # 删除第2行 sed '$d' datafile # 删除最后一行 sed '2,$d' datafile # 删除第2行~末尾所有行 sed '2,5d' datafile # 删除2~5行 sed '/My/,/You/d' datafile # 删除包含My的行~You的行的内容 sed '/My/,10d' datafile # 删除包含My的行~第10行的内容 sed '/^test/'d datafile # 删除文件中所有开头是test的行 nl /etc/passwd | sed '/root/d' # 删除包含root的行
p
∶ 列印。将某个选择的资料印出。通常p
会与参数-n
一起用sed -n '3p' datafile # 打印第3行 sed -n '100,200p' datafile # 打印100~200行 chenjindeMacBook-Pro:~ cj$ nl /etc/passwd | sed -n '5,9p' 5 # in single-user mode. At other times this information is provided by 6 # Open Directory. 7 # 8 # See the opendirectoryd(8) man page for additional information about 9 # Open Directory.
n
: 下一行。匹配行的下一行# 打印匹配字符串的下一行 > sed -n '/AAA/{n;p}' 1.txt BBB CCC EEE # 替换匹配行的下一行中的BBB为bbb,打印所有行 > sed '/AAA/{ n; s/BBB/bbb/; }' 1.txt AAA bbb CCC AAA CCC DDD AAA EEE # 注意以下结果不一样 > sed '/AAA/{ n; s/BBB/bbb/; }' 1.txt # 对匹配AAA的下一行进行BBB匹配修改,打印所有行 > sed '/AAA/{ n; s/BBB/bbb/;p}' 1.txt # 对匹配AAA的下一行进行BBB匹配修改,打印所有匹配AAA的下一行 > sed '/AAA/{ n; s/BBB/bbb/p }' 1.txt # 对匹配AAA的下一行进行BBB匹配修改,打印所有匹配AAA的下一行中匹配BBB替换修改的行
q
:退出# 打印完第10行后,退出 > sed '5q' 1.txt AAA BBB CCC AAA CCC
保持空间:
h
: 拷贝模板块的内容到内存中的缓冲区H
: 追加模板块的内容到内存中的缓冲区g
: 获得内存缓冲区的内容,并替代当前模板块中的文本G
: 获得内存缓冲区的内容,并追加到当前模板块文本的后面x
: 表示互换模板块中的文本和缓冲区中的文本> cat 1.txt AAA a BBB b CCC c AAA 1 CCC 3 DDD 4 AAA 1 EEE 5 # 任何包含AAA的行都被复制并追加到该文件的末尾,只保留最后一个匹配行 > sed -e '/AAA/h' -e '$G' 1.txt AAA a BBB b CCC c AAA 1 CCC 3 DDD 4 AAA 1 EEE 5 AAA 1 # 任何包含AAA的行都被复制并追加到该文件的末尾,追加了所有匹配行 > sed -e '/AAA/H' -e '$G' 1.txt AAA a BBB b CCC c AAA 1 CCC 3 DDD 4 AAA 1 EEE 5 AAA a AAA 1 AAA 1 # 把包含AAA的行与CCC行一对一互换 > sed -e '/AAA/h' -e '/CCC/x' 1.txt AAA a BBB b AAA a AAA 1 AAA 1 DDD 4 AAA 1 EEE 5
表达式元字符
^
匹配行开头,eg:^abc
匹配以abc开头的行$
匹配行结尾,eg:abc$
匹配以abc结尾的行.
匹配非换行符的任意一个字符,eg:a.c
可以匹配abc
,adc
,a8c
,...*
匹配任意多个字符,eg:a*c
可以匹配ac
,abc
,adc
,abdc
,...+
匹配某字符出现一次及以上次字符,eg:a+
可以匹配a
,aa
,aaa
,aaaa
,...?
匹配0次或一次字符,eg:a?
可以匹配b
,a
[]
匹配一个指定范围内的字符[ABC]de # 可以匹配Ade,Bde,Cde; [A-Ca-c] #与A-C及a-c范围内的字符匹配; [ABC][DEF] #匹配AD,AE,AF,BD,DE,BF,CD,CE,CF
[^]
匹配一个不在指定范围内的字符,eg:[^ABC]
可以匹配不以A或B或C字母开头的行|
匹配或Desk|Chair #与Desk和Chair中的任一个匹配; (Blue|Black)Berry: #匹配BlueBerry或BlackBerry
{}
匹配次数a{3} 匹配 aaa; a{3,5} 匹配 aaa,aaaa,aaaaa; a{3,} 匹配 aaa,aaaa,aaaaa,aaaaaaa,.... /a\{5,10\}/ 匹配5~10个a的行
\(..\)
匹配子串,并保存匹配的字符。对于匹配到的第一个子串就标记为\1
,依此类推匹配到的第二个结果就是\2
> echo "this is digit 7 in a number" | sed 's/digit \([0-9]\)/\1/' this is 7 in a number > echo "loveable" | sed 's/\(love\)able/\1rs/' lovers
&
保存匹配到的字符> echo "this is a test line" | sed 's/\w\+/[&]/g' # 正则表达式 \w\+ 匹配每一个单词,使用 [&] 替换它,& 对应于之前所匹配到的单词 [this] [is] [a] [test] [line] > sed 's/^192.168.0.1/&localhost/' file # 所有以192.168.0.1开头的行都会被替换成它自已加localhost 192.168.0.1localhost Hello 192.210.0.1 Do you know 192.168.0.1localhost World
\<
匹配单词的开始\>
匹配单词的结束,eg:/love\>/
匹配包含以love结尾的单词的行
注意:
\s
匹配任意的空白符,包括空格,制表符(Tab),换行符,中文全角空格\S
匹配任意不是空白符的字符.*
在使整个表达式能得到匹配的前提下,匹配尽可能多的字符(贪婪匹配) eg:aabab
->a.*b
->aabab
.*?
在使整个表达式能得到匹配的前提下,匹配尽可能少的字符(懒惰匹配) eg:aabab
->a.*?b
->aab
,ab
- 定址:
- 决定对哪些行进行编辑(可以是数字、正则表达式、或二者的结合,默认为输入文件的所有行。
- 注:数字表示行号,
$
表示最后一行
- 定界符:
- 命令中字符
/
在sed中作为定界符使用,也可以使用任意的定界符, 定界符出现在样式内部时,需要使用\
进行转义
- 命令中字符
- 引用:sed表达式可以使用单引号
''
来引用,但是如果表达式内部包含变量字符串,就需要使用双引号""
set test=Hello echo "Hello WORLD,How are you?" | sed "s/$test/HELLO" HELLO WORLD
示例:
# <SGUID isNull="true"></SGUID>` => `<SGUID>xxxxxxxx</SGUID>
> echo "<SGUID>1234AJD839D</SGUID>" | sed -e 's|<SGUID>[0-9A-Z]\{1,\}</SGUID>|<SGUID isNull="true"></SGUID>|g'
<SGUID>xxxxxxxx</SGUID>
> cat a.txt
<Test bind_variables="{A=801,B=DD Flex}" view_criteria="[PrimaryKeyCriteria]" partitionkey_value="ABC"/>
> grep -oP "bind_variables=[^\s]\{.*?\}[^\s]" a.txt
bind_variables="{A=801,B=DD Flex}"
> grep -oP "bind_variables=[^\s]\{.*?\}[^\s]" sdf.txt | sed 's/{\(.*\)}/\1/g'
bind_variables="A=801,B=DD Flex"
> grep -oP "bind_variables=[^\s]\{.*?\}[^\s]" sdf.txt | awk -F'[{}]' '{print $2}'
A=801,B=DD Flex
> grep -oP "view_criteria=[^\s]\[.*?\][^\s]" sdf.txt
view_criteria="[PrimaryKeyCriteria]"
> grep -oP "view_criteria=[^\s]\[.*?\][^\s]" sdf.txt | awk -F'[][]' '{print $2}'
PrimaryKeyCriteria
> grep -oP "partitionkey_value=[^\s]\w+[^\s]" sdf.txt
partitionkey_value="ABC"
> grep -oP "partitionkey_value=[^\s]\w+[^\s]" sdf.txt | awk -F'[""]' '{print $2}'
ABC
> grep -oP "partitionkey_value=[^\s]\w+[^\s]" sdf.txt | awk -F= '{print $2}' | sed s/\"/\'/g
'ABC'
uniq
> uniq --help
-c, --count prefix lines by the number of occurrences 在每行前面显示该行重复次数
-d, --repeated only print duplicate lines, one for each group 只输出重复的行
-D, --all-repeated[=METHOD] print all duplicate lines 只输出重复的行,有几行输出几行
groups can be delimited with an empty line
METHOD={none(default),prepend,separate}
-f, --skip-fields=N avoid comparing the first N fields 忽略的段数,eg: -f 1 忽略第一段
--group[=METHOD] show all items, separating groups with an empty line
METHOD={separate(default),prepend,append,both}
-i, --ignore-case ignore differences in case when comparing 不区分大小写
-s, --skip-chars=N avoid comparing the first N characters 忽略N个字符
-u, --unique only print unique lines 去除重复的后,全部显示出来,即列出唯一项
-z, --zero-terminated end lines with 0 byte, not newline
-w, --check-chars=N compare no more than N characters in lines 只检查N个以内的字符,之外的不做对照
示例:
测试数据:
> cat test.txt
this is a test
this is a test
this is a test
i am tank
i love tank
i love tank
this is a test
whom have a try
WhoM have a try
you have a try
i want to abroad
those are good men
we are good men
-c
在每行前面显示该行重复次数,注意:检查重复行的时候,只会检查相邻的行> uniq -c test.txt 3 this is a test 1 i am tank 2 i love tank 1 this is a test 1 whom have a try 1 WhoM have a try 1 you have a try 1 i want to abroad 1 those are good men 1 we are good men
- 排序后统计重复次数(解决只用-c统计的不准确问题)
> sort test.txt | uniq -c 1 WhoM have a try 1 i am tank 2 i love tank 1 i want to abroad 4 this is a test 1 those are good men 1 we are good men 1 whom have a try 1 you have a try
-d
只输出重复的行> uniq -d -c test.txt 3 this is a test 2 i love tank
-D
只输出重复的行,有几行输出几行,注意:不能和-c
一起使用> uniq -D test.txt this is a test this is a test this is a test i love tank i love tank
-f
忽略第某列统计> uniq -f 1 -d -c test.txt 3 this is a test 2 i love tank 2 whom have a try 2 those are good men > uniq -f 1 -D test.txt this is a test this is a test this is a test i love tank i love tank whom have a try WhoM have a try those are good men we are good men
-s
忽略前4个字符进行统计> uniq -s 4 -D test.txt this is a test this is a test this is a test i love tank i love tank whom have a try WhoM have a try you have a try
-w
只统计前2个字符> uniq -w 2 -D test.txt this is a test this is a test this is a test i am tank i love tank i love tank
-i
忽略大小写> uniq -i -D test.txt this is a test this is a test this is a test i love tank i love tank whom have a try WhoM have a try
-u
列出唯一项(count为1)> uniq -u test.txt i am tank this is a test whom have a try WhoM have a try you have a try i want to abroad those are good men we are good men > uniq -u -i test.txt i am tank this is a test you have a try i want to abroad those are good men we are good men
curl
Command Line URL viewer,是一种命令行工具,用来发送网络请求
-#, --progress-bar Make curl display a simple progress bar instead of the more informational standard meter.
-b, --cookie <name=data> Supply cookie with request. If no =, then specifies the cookie file to use (see -c).
-c, --cookie-jar <file name> File to save response cookies to.
-d, --data <data> Send specified data in POST request. Details provided below.
-f, --fail Fail silently (don not output HTML error form if returned).
-F, --form <name=content> Submit form data.
-H, --header <header> Headers to supply with request.
-i, --include Include HTTP headers in the output.
-I, --head Fetch headers only.
-k, --insecure Allow insecure connections to succeed.
-L, --location Follow redirects.
-o, --output <file> Write output to . Can use --create-dirs in conjunction with this to create any directories specified in the -o path.
-O, --remote-name Write output to file named like the remote file (only writes to current directory).
-s, --silent Silent (quiet) mode. Use with -S to force it to show errors.
-v, --verbose Provide more information (useful for debugging).
-w, --write-out <format> Make curl display information on stdout after a completed transfer. See man page for more details on available variables. Convenient way to force curl to append a newline to output: -w "\n" (can add to ~/.curlrc).
-X, --request The request method to use.
显示:
-i
/-l
/-v
/--trace
curl -i www.example.com # 显示全部信息 curl -l www.example.com # 只显示头部信息 curl -v www.example.com # 显示一次请求全过程解析 curl --trace output.txt www.example.com # 可显示更详细的通信过程
HTTP Method:
-X
curl -X GET www.example.com # 同 curl www.example.com curl -X PUT www.example.com curl -X POST www.example.com curl -X DELETE www.example.com
指定发送数据:
-d
(--data
) /--data-urlencode
(自动转义特殊字符) /-F
(--form
)# curl -X POST -d "username=Tom&password=123" http://www.example.com/login # 使用了-d,默认即POST方法,可省略 -X POST curl -d "username=Tom&password=123" http://www.example.com/login # curl http://www.example.com/login?username=Tom&password=123 curl -G -d "username=Tom&password=123" http://www.example.com/login # PUT curl -X PUT -d "username=Tom&password=345" http://www.example.com/change
curl --data @localFilename http://www.example.com/login
curl -X POST -F 'username=Tom' -F 'password=123' http://www.example.com/login
-d
为application/x-www-url-encoded
方式-F
为multipart/form-data
方式- 注意:如果在一次curl中同时使用
-d
和-F
选项会报Warning: You can only select one HTTP request!
的警告,导致指令无法执行
自定义头信息:
-H
(--header
)curl -H "Content-Type: application/json" -X POST -d '{"key1":"value1", "key2":"value2"}' http://localhost:3000/data
文件上传:
-F
(--form
) ,request会添加enctype="multipart/form-data"
/-T
(--upload-file <file>
)<!DOCTYPE html> <meta charset="utf-8"> <body> <form method="POST" action='/submit' enctype="multipart/form-data"> <input type="text" name="user"><br> <input type="file" name="img"><br> <input type="submit"> </form>
curl --form img=@localFilename --form user=Tom http://www.example.com/submit curl -F 'img=@localFilename' http://www.example.com/submit?user=Tom
curl -F 'fileX=@pathToFileX' -F 'fileY=@pathToFileY' http://www.example.com/upload # Upload multiple files curl -F 'files[]=@pathToFileX' -F 'files[]=@pathToFileY' http://www.example.com/upload # Upload an array of file
curl -u ftpuser:ftppass -T myfile.txt ftp://ftp.testserver.com # 将myfile.txt文件上传到服务器 curl -u ftpuser:ftppass -T "{file1,file2}" ftp://ftp.testserver.com # 同时上传多个文件 curl -u ftpuser:ftppass -T - ftp://ftp.testserver.com/myfile_1.txt # 从标准输入获取内容保存到服务器指定的文件中
下载文件:
-o <filename>
指定保存文件 /-O
直接使用URL中文件名保存 />
重定向,保存响应结果到指定路径的文件中curl -o mytest.txt http://www.example.com/test.html curl -O http://www.example.com/test.html curl http://www.example.com/test.html > index.html
curl -o filename1 URL1 -o filename2 URL2 # 同时下载多个文件 curl -O URL1 -O URL2
curl -u ftpuser:ftppass -O ftp://ftp_server/public_html/ # 列出public_html下的所有文件夹和文件 curl -u ftpuser:ftppass -O ftp://ftp_server/public_html/xss.php # 下载xss.php文件
cookie:
-c
保存cookie信息 /-D
保存整个header信息,包括cookie /-b
携带cookie信息发送请求curl -c cookie.txt -d "username=Tom&password=123" http://www.example.com/login curl -b cookie.txt http://www.example.com/admin
跳转:
-L
表示追踪重定向 / -e(--referer
) 在http request头信息中,增加一个referer字段,表示来源网址curl -L http://www.example.com/login curl -e http://www.yourblog.com http://www.example.com # 会让服务器其以为你是从http://www.yourblog.com点击某个链接过来的
User Agent:
-A
(--user-agent
) 自定义用户代理# 客户端的设备信息。服务器有时会根据这个字段,针对不同设备,返回不同格式的网页,比如手机版和桌面版 curl -A “Mozilla/5.0 (Android; Mobile; rv:35.0) Gecko/35.0 Firefox/35.0” http://www.baidu.com # 伪装成安卓火狐浏览器对网页进行请求 curl URL -A "Mozilla/5.0" curl URL --user-agent "Mozilla/5.0"
认证:
-u
(--user
) 设置服务器的用户名和密码,可用于HTTP,FTP的认证curl -u user:pwd URL # 可以指定密码 curl -u user URL # 可在后续操作中输入密码
示例:
curl -i -H "Content-Type:application/json" -X POST -d '{"name": "cj", "password":"123456"}' http://127.0.0.1:8080/micro-auth/login
curl -i -H "Content-Type:application/json" -H "micro-auth:1184e49a-8271-4de7-9323-c5f8c81c7cac" -X POST http://127.0.0.1:8080/micro-auth/authentication
crontab
基本格式:M H D m d cmd
- M: 分鐘(0-59)
- H: 小時(0-23)
- D: 天(1-31)
- m: 月(1-12)
- d: 一星期內的天(0~6,0為星期天)
- cmd:要運行的程序,程序被送入shell執行
- 例如:
# MIN HOUR DAY MONTH DAYOFWEEK COMMAND 10 6 * * * date test.sh # 每天早上6:10 0 */2 * * * date test.sh # 每隔两小时 0 23-7/2,8 * * * date test.sh # 晚上11点到早上7点之间,每隔一小时 0 11 4 * mon-wed date test.sh # 每月的4号与每星期一至星期三的早上11点
crontab命令:
crontab file [-u user]
用指定的文件替代目前的crontab.crontab -[-u user]
用標准輸入替代目前的crontab.crontab -l[user]
列出用戶目前的crontab.crontab -e[user]
編輯用戶目前的crontab.crontab -d[user]
刪除用戶目前的crontab.crontab -c dir
指定crontab的目錄- eg: 列出用戶目前的crontab
> crontab -l 10 6 * * * hello.sh 40 10 01 * * java -jar InitContract.jar >/dev/null 00 16 * * * /bin/ksh leave.sh > leave_update.log
示例:
- 编写shell,并赋予执行权限
chmod +x file.sh # csh -x file.sh # ksh -x file.sh
- 导出现有crontab
crontab -l > test_crontab
- 编辑导出的crontab文件,添加crontab任务
vi test_crontab
- 导入新的crontab文件,使其生效
crontab test_crontab
Shell
# 查看當前使用的Shell
> echo $SHELL
/bin/sh
# 查看当前shell的进程号
> echo $$
12282
# ps-A看自己shell的pid
> ps -A | grep 12282
12282 pts/19 0:00 sh
# 启动一个新的K Shell进程,用exit退出
> ksh
> exit
# 启动一个新的C Shell进程,用exit退出
> csh
> exit
命令回传值
$?
- 若前一个命令运行的结果为正确,在 Linux 底下会回传一个 $? = 0 的值
cmd1 && cmd2
- 若 cmd1 运行完毕且正确运行(
$?=0
),则开始运行 cmd2 - 若 cmd1 运行完毕且为错误 (
$?≠0
),则 cmd2 不运行
- 若 cmd1 运行完毕且正确运行(
cmd1 || cmd2
- 若 cmd1 运行完毕且正确运行(
$?=0
),则 cmd2 不运行 + 若 cmd1 运行完毕且为错误 ($?≠0
),则开始运行 cmd2
- 若 cmd1 运行完毕且正确运行(
示例:
# 自动判断,如果没有该目录就给予创建 ls /tmp/abc || mkdir /tmp/abc # 以 ls 测试 /tmp/vbirding 是否存在 # 若存在则显示 "exist" # 若不存在,则显示 "not exist" ls /tmp/vbirding && echo "exist" || echo "not exist"
exit n
- n 是数字
- 让程序中断,并回传一个数值给系统
- 利用此功能,可以自订错误信息,并通过
echo $?
获取错误信息
变量
变量的测试与内容替换
变量配置方式 str 不存在 str 为空字符串 str 为非空字符串 『判断』str是否存在 str不存在,返回expr str存在,返回str原值 var=${str-expr}
var=expr var= var=$str var=${str:-expr}
var=expr var=expr var=$str 『判断』str是否不存在 str不存在,返回空 |str存在,返回expr var=${str+expr}
var= var=expr var=expr var=${str:+expr}
var= var= var=expr 使用等号 =
str不存在,返回expr,且置str=expr str存在,返回str原值,str不变 var=${str=expr}
var=expr , str=expr var= ,str 不变 var=$str, str 不变 var=${str:=expr}
var=expr , str=expr var=expr, str=expr var=$str, str 不变 使用 ?
str不存在,expr 输出至 stderr str存在,返回str原值 var=${str?expr}
expr 输出至 stderr var= var=$str var=${str:?expr}
expr 输出至 stderr expr 输出至stderr var=$str - 注意: 使用
:
则变量不存在或为空字符串则是一个效果 打印变量
> echo $var 1 # 扩展$var并添加串work # {} 把该变量从给它添加的字符里分离出来 > echo ${var}work 1work
日期date
> date Tue Feb 7 15:35:15 CST 2012 > echo `date +%y%m%d` 120207 > echo `date +%Y/%m/%d` 2012/02/07 > echo `date '+%H%M%S'` 153255 > echo `date +%D` 02/07/12 > echo `date +%h` Feb > echo `date '+%Y/%m/%d %H:%M:%S'` 2012/02/07 15:32:35
date1=$(date --date='2 days ago' +%Y%m%d) # 前两天的日期 date2=$(date --date='1 days ago' +%Y%m%d) # 前一天的日期 date3=$(date +%Y%m%d) # 今天的日期 # 配置档名 file1=${filename}${date1} file2=${filename}${date2} file3=${filename}${date3}
命令替换:将命令放入反引号
> set d = `date` # 产生的值是一个数组 > echo $d[1] Tue > set d="`date`" # 输出封装在双引号里,所以是一个单串 > echo $d[1] Tue Feb 7 13:33:06 CST 2012 > echo $d[2] Subscript out of range > cal 2 2012 February 2012 S M Tu W Th F S 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 > echo Hello `cal 2 2012` # 输出每个换行符都用一个空格代替 Hello February 2012 S M Tu W Th F S 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
C Shell
#!/bin/csh
用户接收
$<
echo -n "What is your name? " # -n 取消末尾的换行 set name = $<
测试变量是否被设置
$?var
- 1:设置了
- 0:未设置
- eg:
echo $?hello
命令行变元
$xxx
$0,$1,$2,... $* $argv[0] $argv[1],$argv[2],...$argv[$#argv] $argv[*],$argv
数值运算
> @ sum = 4 + 6 > echo $sum 10 > @ sum ++ > echo $sum 11 > @ sum += 3 > echo $sum 14
数组
(...)
创建数组$#var
数组长度$var[*]
,$var
打印所有元素$var[..]
获取某个数组元素(数组从1~len)shift var
数组左移一个元素> set name = "Hello GoodBye Sir" > echo $name[1] Hello GoodBye Sir > echo $name[2] Subscript out of range # 将变量封装在()中,创建一个叫做fruit的数组 > set fruit = ($name) > echo $fruit Hello GoodBye Sir > echo $fruit[2] GoodBye
# 创建数组 > set fruit = ( app1 app2 app3 ) > echo $fruit app1 app2 app3 > echo $fruit[*] app1 app2 app3 # 查询 > echo $fruit[1] app1 > echo $fruit[2-3] app2 app3 > echo $#fruit 3 > echo $fruit[$#fruit] app3 # 操作 > set fruit[2] = bana > echo $fruit app1 bana app3 > shift fruit > echo $fruit bana app3
条件表达式
==
,!=
,>
,>=
,<
,<=
,~
,!~
,!
,||
,&&
if ( $answer =~ [Yy]* ) then if ( $status == 0 ) then if ( $?prompt ) then if ( "$name" != "KK" ) then #使用“”防止name中不止一个词而发生异常 if ( ("$x" && "$y" ) || ! "$z" ) then # ! 后面必须有一个空格
-r
,-w
,-x
,-o
if ( -r $file && -w $file ) then
-e
,-z
,-f
,-d
if ( ! -d $file ) then
条件判断
if/else if/else/endif
if ( exp1 ) then echo "case1" else if ( exp2 ) then echo "case2" else if ( exp3 ) then echo "case3" else echo "case4" endif
switch/case/breaksw/endsw
switch ( str ) case red: echo "case1" breaksw case bl*: echo "case2" breaksw case [56].c: echo "case1" breaksw default: breaksw endsw
循环
foreach var (list) cmd end
foreach person (`cat maillist`) echo $preson end
foreach file (*.c) echo $file end
while(exp) cmd end
while ( $num < 10 ) echo $num @ num++ end
while ( "$answer" != "Bye" ) set answer = $< end
while ($#argv) echo $argv shift end
while (1) cmd if () then break else if () then continue else cmd endif end
repeat n cmd
repeat 3 echo hello
示例
设置变量
set FTP_FTSERVER = (10.7.49.15 10.7.49.17 10.7.49.152 10.7.54.2) set ServletURL = http://10.7.33.16/cim/servlet set Rawdata = $downup\/$LOTNO-$CPNO
set tdtplogfile = /home/klt/log/tdtp_1.`date '+%Y%m%d'` set LOGS = /db/data/autoftp/logs/pixart/`/usr/ucb/whoami`
set tmpfile = /home/klt/wgetlog/$$ set TEMPLASER = /home/cim1tdtp/temp/"$LLOTNO$WAFNUM"-$$.asc
set lenOfPfile = `echo $proberfile | cut -d '/' -f8 | awk '{print length($1)}'` set lenOfWno = `echo $proberfile | cut -d '/' -f8 | cut -d '.' -f1 | awk '{print length($1)}'` @ lenOfWno = $lenOfWno + 2 set partlotno = `echo $proberfile | cut -d '/' -f8 | cut -c $lenOfWno-$lenOfPfile` echo partlotno is $partlotno set fproberfile = `ls /db/prober/map/$testgrp/$Rawdata/$partlotno=* | tail -1` set fpfilelength = ` echo $fproberfile | awk '{print length($1)}'`
set cpNo = `echo $configArr[1] | cut -c 3- ` set USER_COUNTS = `who | grep klt | wc -l` set os = `uname` set RETURNVALUE=`echo $TMPLINE |awk -F\| '{print $1}'` set RemoteHost = `who am i |awk '{print $NF}' | awk -F\( '{print $2}' | awk -F\) '{print $1}' | awk -F. '{print $1}' `
接收用户输入
- 存入一个变量
echo CPNO: set CPNO = $<
存入数组,小写转换为大写,获取字符串长度,设置变量
echo CPNO Flotno WaferNum PROBERIP TESTGROUP UP set tempfile = $< set file = ($tempfile) if ( $#file == 6 ) then set CPNO = `echo $file[1] | tr "[:lower:]" "[:upper:]" ` set equip = $file[4] set numchar = ` echo $WAFERNUM | awk '{print length($1)}'` endif if ( $numchar == 1 ) then set WAFERNUM = 0"$WAFERNUM" endif
- 存入一个变量
if 判断
if (-e $tmpfile) then echo `date '+%H:%M:%S'` >> $tdtplogfile endif if ( ! -d $LOGS ) then mkdir -p $LOGS endif if ( ! -d $FTP_SRC_DIR ) then mkdir $FTP_SRC_DIR chmod 777 $FTP_SRC_DIR endif
if ( $USER_COUNTS > 3 ) then echo "Too Many User Execute TDTP manual(Default:3 users), Please wait..." echo "You can contact with user, and list as follows:" who | grep klt ps -ef | grep " klt " exit endif if ($os =~ [Ll][Ii][Nn][Uu][Xx]) then set wget = $srcpath"download-Linux" else if ($os =~ [Ss][Uu][Nn][Oo][Ss]) then if ( `hostname` =~ [Jj]995*) then set wget = $srcpath"download-SunOS41" else set wget = $srcpath"download-SunOS" endif endif if ($os !~ [Ll][Ii][Nn][Uu][Xx]) then unsetenv $PGM_WGETPATH endif
# $status : # grep 找到所寻找的模式 0; 找不到该模式 1; 找不到文件 2 ; # awk / sed 不论搜索的模式是否成功 0 ; 语法错误 非0 grep "tw.com.kyec.cim.cp.task.TaskTDTPProber: true" $tmpfile > & /dev/null if ($status == 0 ) then echo TDTP have done $proberfile else echo failed to do TDTP $proberfile endif set fproberfile = `ls /db/prober/map/$testertype/up/$templotno/$partlotno=* | tail -1` set fpfilelength = ` echo $fproberfile | awk '{print length($1)}'`
foreach 循环
foreach FTP_SERVER ( `echo $FTP_FTSERVER`) /usr/sbin/ping $FTP_SERVER | grep alive >& /dev/null if ( $status != 0 ) then echo Server can\'t connect to $FTP_SERVER >> $FTP_LOG continue endif end
set count = 1 foreach filename (`cat $FileList`) set klotno = `echo $filename | cut -d'-' -f1` set barcode = `echo $filename | cut -d'_' -f1` set filetime = `echo $filename | cut -d'_' -f2 | cut -c 1-12` if ( $klotno == $lotno ) then set cmdStr = "$ServletURL/chkWfrStatus?CUST=ZKT&2DBARCODE=${barcode}&STNO=1&FILETIME=${filetime}&TESTER=E320_BDB01&HEAD=1" $WGET -q -O $tmpfile "$cmdStr" @ count++ else echo "$klotno != $lotno" >> $logfile endif end
while 循环
set waferno = 1 while ( $waferno < 26 ) @ waferno = $waferno + 1 if ($waferno < 10 ) then continue endif end
while ( $#argv > 0 ) set args = "$args $argv[1]" shift argv end
压缩/解压缩
unzip -o $FTP_AIM_DIR/$LOTNO/$TEMP_FILE -d $FTP_AIM_DIR/$LOTNO/ unzip $TEMP_ZIP1.zip -d $TEMP_ZIP1.ZIP uncompress < $FTP_AIM_DIR/$LOTNO/$TEMP_FILE | tar xf - tar -cvf $DirName".tar" $DirName compress $DirName".tar"
环境变量设置
set srcpath = "/cim/pgm/prod/" setenv PGM_WGETPATH $srcpath setenv CIM_AUTO_INVOKED_PRCESS /home/asx/bin/auto_prober_klt.sh setenv CDC_PROBERD_LICENSE "O54k43jL7aI2LGaBo6bf6IxaLPQtc2"
FTP
# ftp -inv $FTP_SERVER echo user $FTP_USER $FTP_PASSWORD >> $FTP_CMD_FILE echo cd /down >> $FTP_CMD_FILE echo bin >> $FTP_CMD_FILE echo put $file >> $FTP_CMD_FILE echo bye >> $FTP_CMD_FILE ftp -inv $FTP_SERVER < $FTP_CMD_FILE echo "OK\!"
echo user $FTP_USER $FTP_PASSWD > $FTP_CMD_FILE echo cd $FTP_DIR_A >> $FTP_CMD_FILE echo bin >> $FTP_CMD_FILE echo "mget C*.TXT" >> $FTP_CMD_FILE echo "mdir C*.TXT $DB_LOG" >> $FTP_CMD_FILE foreach TEMP_FILE ( C*.TXT ) echo "del $TEMP_FILE" >> $FTP_CMD_FILE end ls *.zip | awk '{printf "del %s\n",$1}' >> $FTP_CMD_FILE echo bye >> $FTP_CMD_FILE echo "## start get emap data from csmc ftp Server at `date` ##" >> $FTP_LOG (ftp -inv $FTP_SERVER < $FTP_CMD_FILE) >> $FTP_LOG echo "## end get emap data from csmc ftp Server at`date` ##" >> $FTP_LOG
特殊命令
java -classpath .:/home/asx/proberlog/classes12.jar probLogScan $proberfile /home/asx/proberlog/ unix2dos $LLOTNO$WAFNUM.asc $LLOTNO$WAFNUM.asc exec /home/asx/bin/cdc_proberd > /home/asx/bin/cdc_screen.log.`date '+%Y%m%d'` last | grep logged | grep tsk | grep $RemoteHost >& /dev/null /home/asx/bin/auto_prober_real_klt.sh $1 $2 & sed -n 17,"$FILE_LENGTH"p $FILE > $tmpfile set CAT_X = `perl -e 'while(<>){$count+= s/X//g;} print "$count";' $tmpfile` set lineSting = `sed -n $line"p" $FILE_SHARE_TMP`
使用wget 触发 Servlet
set WGET = /cim/bin/wget/ADVAN/wget $WGET -q -O $tmpfile "$ServletURL/CpTrigger?TASK=$TASK"
调用java
#! /bin/csh #classpath=.:$JAVA_HOME/lib/tools.jar:/home/cim1tdtp/oracle.jar set srcPath="/db/data/CGSPGM/exec" cd $srcPath echo `java ParseRawForCGS` >> insertResult.txt exit
K Shell
#!/bin/ksh
读取用户输入
read
read # $REPLY read answer print $answer read first middle last read -u3 name # -u 从文件描述符中读取一行存储到变量name中 while read -u3 line1 && read -u4 line2 do print "$line1:$line2" done 3<$1 4<$2
只读
readonly
> readonly name=Tom > print $name Tom > name=Joe ksh: name: is read only
typeset
设置变量属性-u
将变量值中所有字母全部转换成大写-l
将变量值中所有字母全部转换成小写-i
将变量值设为整数类型-L
width 在width宽度之内左对齐-R
width 在width宽度之内右对齐,前面空位用空格填充-Z
width 在width宽度之内右对齐-x
设置一个全局变量。相当于 export-r
设置一个变量具有只读属性,相当于readonly> typeset -i num # 整数 > typeset -i2 num # 将数值num转换为二进制,i后面为进制数 > print $num 2#111 > kk=5.6 > typeset -i kk > echo $kk
history
history history -n # print without line numbers history 8 # list form 8th command to present history -3 # list this command and the 3 preceding it history -1 -5 # list last 5 commands,preceding this one in reversed order history -5 -1 # list last 5 commands,preceding this one in order history ls echo # display from most recent "ls" command to most recent "echo" command history -r ls echo # -r reverses the list
r
重新执行命令r date r 3 r vi r vi file1=file2
别名
alias
alias c1='clear' alias l='ls -laF' unalias c1 alias -t
命令行变元
> set tom joe sam > echo $* tom joe sam > shift > echo $* joe sam > echo $# 2 > set $(date) > print $* Wed Feb 8 14:41:11 CST 2012 > shift 3 > print $* 14:41:11 CST 2012
算数运算
num=5 let num=num+2 # (( num=num+2)) print $num
数组
set -A var ...
创建数组${var[*]}
打印数组${var[..]}
获取数组某元素值
> typeset -i names[4] > names[0]=30 > set -A fruit apples pears bananana > print $fruit apples > print ${fruit[1]} pears > print ${fruit[*]} apples pears bananana > print ${#fruit[*]} # 数组长度 3
函数
function funcName { cmd;} $funcName
function funCName {print "Hi $1 and $2";) $funcName tom joe > typeset -f funCName # list function define > typeset +f funCName # list function name > unset -f funCName # clear funtion
条件判断
- 整数测试:
-eq
,-ne
,-gt
,-ge
,-lt
,-le
- 文件测试:
-r
,-w
,-x
,-d
,-f
,-s
,-e,
-a` - 逻辑操作符:
&&
,||
,!
[]
等价于旧 test 命令 ([
后面必须有空格)[[]]
/(())
等价于新test 命令,允许使用Shell元字符扩展> name=Tom > test $name=Tome > [ $name = Tom ] > [[ $name = [Tt]?m ]]
- 整数测试:
判断
if/elif/else/fi
if [[ ... ]] then cmd elif [[ ... ]] cmd else cmd fi
case/esac
case var in value1) cmd ;; value2) cmd ;; *) cmd ;; esac
循环
for var in list do cmd done
for person in `cat mylist` # for person in $(<mylist) do print $person done
-
while [[expr]] do cmd done
while (( num < 10 )) do print $num (( num=num+1)) done
while [[ $answer != "Tom" ]] do print "wrong!" read answer done
cat $1 | while read line do print $line done > tmp$$
until [[expr]] do cmd done
until who | grep linda do sleep 5 done
select
select var in wordlist do cmd done
IFS
: shell 内部分隔符names=Tom:Dick:Sam:John OldIFS="$IFS" IFS=":" for person in $names do print Hi $preson done IFS="$OldIFS"
使用示例:
压缩备份资料(压缩文件夹)
#!/bin/ksh read zipPath echo $zipPath cd $zipPath # tar, compress for DirName in `ls ` do tar -cvf $DirName".tar" $DirName compress $DirName".tar" done # zip for DirName in `ls ` do echo $DirName zip -r $DirName".zip" $DirName rm -r $DirName done #collectData=$zipPath/1.txt #echo $collectData #while read DirName #do # echo $DirName # zip -r $DirName".zip" $DirName # rm -r $DirName #done < $collectData echo OK exit
If
if [ ! -d $generatePath ] then mkdir $generatePath fi if [ -f $filePathWithName ] then if [[ $cpno -eq 1 ]] then awk 'NR>21 {print $3" "$4" "$5" "$6" "$7" "$8}' $filePathWithName > $generatePath/$wafid else awk 'NR>21 {print $3" "$4" "$5" "$6" "$7}' $filePathWithName > $generatePath/$wafid fi echo "OK : $wafid " >> $resultLog else echo "FAIL : $count $filePathWithName unfound" >> $resultLog echo "FAIL : $count $filePathWithName unfound" >>$FailLog fi
if [ $TEMPMAXNUM -lt 50 ] if [ $NUM -eq "0" ] if [ -f $FTP_SRC_DIR/$CUSTOMER/$FILE ] if [[ $LOCAL_SIZE == $REMOTE_SIZE ]]
if [ -f $FTP_SRC_DIR/$CUSTOMER/$FYLE_TYPE/*H2T340* ] then if [ ! -d $FTP_SRC_DIR/$CUSTOMER/$FYLE_TYPE/stdfFilter ] then mkdir $FTP_SRC_DIR/$CUSTOMER/$FYLE_TYPE/stdfFilter fi echo $FTP_SRC_DIR/$CUSTOMER/$FYLE_TYPE/*H2T340* mv $FTP_SRC_DIR/$CUSTOMER/$FYLE_TYPE/*H2T340* $FTP_SRC_DIR/$CUSTOMER/$FYLE_TYPE/stdfFilter/ echo "move to stdfFilter ok" fi
while
count=1 while read line do echo $count `date '+%m%d%H%M'` :$line >> $resultLog filename=`echo $line | awk '{print $6}'` generatePath=$resultPath/$klotNo let i=count%5 if [[ $i == 0 ]] then echo "********************************************" >> $resultLog echo $count fi let count=count+1 done < $collectData
usedFilePathLength=1 while (( $usedFilePathLength < ${#arrayFileDir[*]}-1 )) do echo mkdir ${arrayFileDir[$usedFilePathLength]} >> $FTP_CMD_FILE echo cd ${arrayFileDir[$usedFilePathLength]} >> $FTP_CMD_FILE cd ${arrayFileDir[$usedFilePathLength]} let usedFilePathLength=usedFilePathLength+1 done
B Shell
#!/bin/bash
read
read -p "Please input your first name: " firstname # 提示使用者输入 read -p "Please input your last name: " lastname # 提示使用者输入 echo -e "\nYour full name is: $firstname $lastname" # 结果输出
数值运算 ( bash shell 默认仅支持到整数的数据 )
var=$((运算内容)) echo $(( 13 % 3 ))
更多可参考:鸟哥的Linux私房菜
注意
shell脚本执行错误 $'\r':command not found
原因:
脚本是在window下编辑完成后上传到linux上执行的,win下的换行是回车符+换行符,也就是\r\n
,而unix下是换行符\n
。
linux下不识别\r
为回车符,所以导致每行的配置都多了个\r
,因此是脚本编码的问题。
解决方案:
在linux上执行 dos2unix 脚本名
,再次执行脚本,报错消失
> dos2unix a.sh
> ./a.sh # 或 sh a.sh