【汇总】sh语法汇总
?
?
test -d $nginx_path || mkdir -p $nginx_path
?
?
============== 单引 双引 反引用 []?? [[]]
?
?
hard quote:单引号,关闭所有的meta(什么是meta,自己查吧)
soft quote:双引号,关闭大部分的meta,但是某些保留,例如$,括在双引号中的三种特殊字符不被忽略:$,\,`
反引用``相当于$(),反引号内不能再引用反引号,而$()中可以引用反引号
?
?
?
将命令的输出读入一个变量中,可以将它放入双引号中,即可保留空格和换行符(\n)
out=$(cat text.txt)
输出1 2 3
out="$(cat text.txt)"
输出:
1
2
3
?
?
--------------[]一般用于算术比较
?
-gt 大于
-lt?? 小于
-ge? 大于等于
-le?? 小于等于
?
逻辑与-a
[ $var1 -eq 0? -a $var2 -gt 2 ]
?
逻辑或
[ $var1 -eq 0? -o $var2 -gt 2 ]
?
[ condition ] && action 等价于if...fi
?
?
if [ "$LOOK_OUT" -gt "85" ]
?
?
if [ -e /home/slynux ]; then
...
fi
?
-----------------[[]]一般用于字符串比较
?
?
if [[ -n $str1 ]]? && [[ -z $str2 ]] ;
then
commands;
fi
?
?
?
?
?
?
?
========================
?
?
?
?
-----------------获取 名称.扩展名
?
file_jpg="sample.jpg"
name=${file_jpg%.*}
输出sample
?
?
file_jpg="sample.jpg"
extension=${file_jpg#*.}
输出jpg
?
?
------------------ time 计算命令执行时间
?
time command
?
--------------- 重定向
0? stdin标准输入 ??
1? stdout标准输出 ? ?
2? stderr标准错误
?
文件打开模式:
> 等同于1>???????????????????????? 截断模式
>>等同于1>>???????????????????? 追加模式
<用于从文件中读取至stdin??? 只读模式
?
?
?
ls + 2> out.txt
stdout不会有任何输出,因为错误已经重定向到out.txt中了
?
?
?
可以将stderr单独重定向到一个文件,将stdout重定向到另一个文件:
cmd 2>stderr.txt 1>stdout.txt
?
?
将stderr转换成stdout,使得stderr和stdout都被重定向到同一个文件:
cmd 2>&1 output.txt
或者
cmd &> output.txt
?
将stderr输出丢弃
some_command 2> /dev/null
?
将文件重定向到命令
cmd < file
?
向log文件中写入头部数据
#!/bin/bash
cat <<EOF>log..tt
LOG FILE HEADER
this is a test log file
EOF
?
?
?
/usr/local/shell/automation/update_host.sh> $date_file 2>&1
?
?
----------/dev/null 2>&1
?
*/1 * * * * root /usr/local/php/bin/php /var/w.php > /dev/null 2>&1
?
crontab内容 :50 18 5-30 * * /script/myscript.sh 1> /dev/null 2>&1
其中 1> /dev/null 2>&1是什么意思??
dev/null 为系统垃圾箱
&为后台运行
但是 myscript 后面的1 和 /null后面的2 还有 &后面的1是什么意思?
1代表标准输出,2代表错误信息输出.
1>/dev/null 就是指将标准输出定向到空设备,
2>&1,的意思是将错误输出定向到和1一样的输出设备,也同样是空.
?
换句话说,就是不显示该程序执行过程中的任何信息
cmd >a 2>a 和 cmd >a 2>&1 为什么不同?
cmd >a 2>a :stdout和stderr都直接送往文件 a ,a文件会被打开两遍,由此导致stdout和stderr互相覆盖。
cmd >a 2>&1 :stdout直接送往文件a ,stderr是继承了FD1的管道之后,再被送往文件a 。a文件只被打开一遍,就是FD1将其打开
他们的不同点在于:
cmd >a 2>a 相当于使用了FD1、FD2两个互相竞争使用文件 a 的管道;
而cmd >a 2>&1 只使用了一个管道FD1,但已经包括了stdout和stderr。
从IO效率上来讲,cmd >a 2>&1的效率更高。
?
?
----------------- 算数运算 let expr
?
let 可以直接执行基本的算数操作
?
no1=4
no2=5
let result=no1+no2
echo $result
?
?
?
let no1++
let no1+=6
?
操作符[]? ,expr 和let命令类似
result=$[ no1 + no2 ]
result=$[ $no1 + $no2 ]
result=`expr 3 + 4`
result=$(expr $no1 + 5)
?
?
---------------- 浮点运算 bc
?
#echo "4 * 0.56" | bc
2.24
?
-----------------获得字符串长度
?
var=123456
echo ${#var}
?
?
?
?
?
-----------------环境变量$PATH和export
?
echo $PATH
PATH通常定义在/etc/environment或/etc/profile或~/.bashrc中
?
export命令用来设置环境变量;
?
添加新的路径:
export PATH="$PATH:/home/user/bin"
?
或者
PATH="$PATH:/home/user/bin"
export PATH
?
?
其它环境变量:HOME,PWD,USER,UID,SHELL
?
?
查看进程相关的环境变量:
cat /proc/$PID/environ
?
?
----------------- printf 格式化输出
?
printf "%-5s %-10s %-4s\n" No Name Mark
printf "%-5s %-10s %-4.2f\n" 1 James 91.32
?
?
输出为:
No?????? Name??????? Mark
1???????? James?????? 91.32
?
?
%-5s 指明了一个格式为左对齐且宽度为5的字符串替代(- 表示左对齐)
-4.2f 表示对浮点数的处理格式
?
?
?
-------------- 读取命令返回值$?
?
cmd;
echo $?;
?
?
?
?
?
?
?
?
?
-------------------------shell 调试
?
?
#!/bin/bash -xv 不用任何其他选项就可以启用调试功能了
?
?
sh -n sh16.sh 不执行script,仅查询语法
sh -x sh16.sh 将script执行过程全部列出来
?
?
?
?
需要给变量赋值时,可以这么写:?
?变量名=值?
要取用一个变量的值,只需在变量名前面加一个$
a="hello world"?
echo "A is:" $a
?
?
?
//if 注意空格
a=$1
if [[ $a -eq 2 ]] ;then
?echo "1"
else
?echo "2"
fi
?
if [[ $a = gjslint ]] ;then
?echo "1"
?exit 0
else
?echo "2"
fi
?exit 0
?
?
?
?
===================== 调用php的sh
?
?
#!/bin/bash
?
if [[ $0 = /* ]]?
then?
? ?curfile="$0"?
else ?
? ?curfile="$PWD/${0#./}"
fi
#得到curfile 为 /usr/local/shell/automation/autoupdate_host.sh
?
php_path=`dirname $curfile`
#得到php_path为/usr/local/shell/automation
?
?
?
PHP="/usr/local/php/bin/php -q "
PROGRAM="${php_path}/clear_his.php"
?
#echo $PHP $PROGRAM &
$PHP $PROGRAM &
?
?
?
====================== [和[[有什么不同
??? $ type [
??? [ is a shell builtin
??? $ type [[
??? [[ is a shell keyword
也就是说[处理里面的字串是当作参数来处理的,而[[对待其中的字串是当作表达式来处理的
那么当作参数和表达式有什么不同呢?
表达式中不会有wordsplitting 或者glob expansion,而参数处理会有
??? $ ls
??? file? file 1??????? #注意是2个文件(file 和file 1)
??? $ (foo="file 1";[[ -f $foo ]]&&echo "$foo is a file")
??? file 1 is a file
??? ]$ (foo="file 1";[ -f $foo ]&&echo "$foo is a file")?? # 这里file 1被分成2个word,所以出错
??? bash: [: file: binary operator expected
再来看看glob expansion
??? $ touch '*'
??? $ (foo="*";[ -f $foo ]&&echo "$foo is a file")?? #为什么显示too many arguments,因为 *被扩展为所有目录下的文件
??? bash: [: too many arguments
??? $ (foo="*";[[ -f $foo ]]&&echo "$foo is a file")? # *被当成普通字符了
??? * is a file
参数传递中<和>会被解析成重定向符号,所以必须转义掉
??? $ ([ "s" < "l" ]&&echo yes)????????????? #错误使用
??? bash: l: No such file or directory
??? $ ([ "s" \> "l" ]&&echo yes)?????? #正确使用
??? yes
??? $ ([[ "s" > "l" ]]&&echo yes)???? #而在表达式中比较符号不会被当作重定向符号
??? yes
参数传递中小括号会被分割成token,而在表达式中则会被解析成运算顺序
??? $ ([ "s" \> "l" -a ( file "l" \> "a" -o "l" \> "p" ) ]&&echo yes)? #(和)必须被转义,以避免参数解析中的不正确分词
??? bash: syntax error near unexpected token `('
??? $ ([ "s" \> "l" -a \( "l" \> "a" -o "l" \> "p" \) ]&&echo yes)
??? yes
??? $ ([[ "s" > "l" && ( "l" > "a" || "l" > "p" ) ]]&&echo yes; ) #而表达式则不需要考虑这个
??? yes
?
?
?
?
?
?
==================bash中的特殊符号
?
* 万用字符,代表一个或多个字符(或数字)
? 万用字符,代表一个字母
# 批注,这个最常被使用在 script 当中,视为说明!
\ 跳脱符号,将『特殊字符或万用字符』还原成一般字符
| 分隔两个管线命令的界定;
; 连续性命令的界定(注意!与管线命令并不相同)
~ 使用者的家目录
$ 亦即是变量之前需要加的变量取代值
& 将指令变成背景下工作
! 逻辑运算意义上的『非』 not 的意思!
/ 路径分隔的符号
>, >> 输出导向,分别是『取代』与『累加』
' 单引号,不具有变量置换的功能
" 具有变量置换的功能!
` ` 两个『 ` 』中间为可以先执行的指令!
( ) 在中间为子 shell 的起始与结束
[ ] 在中间为字符的组合
{ } 在中间为命令区块的组合!
?
?
?
exit 1:退出整个程序
?
?
?
?
--------------------dirname
?
dirname? /home/bin/abc
得到/home/bin
?
?
?
?
?
------------------------- 循环读取每行:
all_corp=sql.txt
cat $all_corp | while read line
do
??? echo $line
done
?
?
awk \'{print $2}\' class.txt | grep \'^[0-9.]\' >res
iptables 配置文件目录 /etc/sysconfig/iptables
1.别名 alias,存放位置 $HOME/.bashrc
alias ll=\'ls -lh\'
2.print=helloworld echo ${print}
3.变量:内存中一块存储单元
本地变量:登陆登出生命周期内有效,只限制于本用户
变量名=变量值
set 查看
LOCAL="TEST"
echo $LOCAL
设置变量名为只读,不能在更改,同是也不能在恢复:readonly 变量名,不能删除。
环境变量:系统变量,用于所有用户,只有环境变量才能用于所有的子进程中,本地变量不可以。
存放于/etc/profile .bash_profile
export 变量名=变量值
env或者export查看
unset 变量名 删除
变量替换:用变量的值替换变量的名
print=helloworld
echo ${print}
echo ${file1}+${file2}
--------------------位置变量:$0 $1...$9
$0:脚本的名字
$1:脚本的第一变量
$2:脚本的第二变量
向脚本中使用位置参数:./test.sh a b c
向系统命令传递参数
find /root/ -name $1 -print
./test.sh aa
标准变量:bash默认的,可以在/etc/profile中定义
EXINIT
HOME
IFS:设置分隔符,默认为空格 IFS=":"SHE
LOGNAME
MAIL 默认邮箱位置
MAILPATH多个邮箱时可以设置
TERM 显示终端类型
PS1 当前shell目录格式PS1="WANGJIAN:"
ps2 >
pwd显示当前路径 SHELL 显示当前shell
MANPATH TERMINFO
?
----------------------特殊变量
$# 变量的个数 $* 显示脚本全部参数(参数列表)
$$脚本运行的当前id号
$?显示前一个命令的运行状态
$!后台运行的最后一个进程id号
#!/bin/bash
echo "tesh.sh"
echo "this is first variable locate:$1"
echo "this is second variable locate:$2"
echo "this is third variable locate:$3"
shift
echo "count:$#"
echo "all list:$*"
echo "pid:$$"
echo "status:$?"
./tesh.sh a b c
declare :设置或显示变量 -f只显示函数名
export:创建环境变量 -p显示所有环境变量
readonly:设置只读变量,不能修改删除
unset:取消变量的定义。-f 删除只读变量
shift:输入的位置变量改变位置 shift 表位置上移一个位置,shift 2 表上移动两个位置
双引号"":引用字符或字符串除$ \ `
单引号\'\':直接引用为字符或字符串
反引号``: 作为系统命令执行 echo `echo wangjian` wangjian
反斜杆\:转义特殊字符($*?)为普通字符
运算符:~取反 <<>>移位 &与(同1为1,否0)|或(有1为1,全0为0) ^异或 逻辑运算符号&& ||
运用运算符:$[]:表示对其中的表达式求值 echo $[2+8] echo $[3&4]$[]等价于(())
[base#n] n(base>n)表示基数从2到36的任何基数 echo [10#8+1]结果为9
let a+=3 a=a+3
表达式优先级别[] *= || && | ^& ==
shell 的输入与输出
echo
-e 解析转义字符 echo -e "this is a bag \n\n\n"
-n 回车不换行,默认换行 echo -n "this is a cat"
转义字符(\c回车不换行 \f禁止 \t跳格相当tab \n回车换行)
read:可以从键盘或文件的某一行文本中读入信息,并将其赋给一个变量。
read varible1 varible2
如果只指定了一个变量,那么read将会把所有的输入赋给改变量,直至遇到文件结束或回车。如果多个变量,就依次赋给。shell用空格作为变量之间的分隔符。
echo -n "first name:"
read firstname
echo -n "last name:"
read lastname
echo -e "your first name :${firstname}\n"
echo -e "your last name :${lastname}\n "
read -t 5 variable 5秒钟超时
read -p "Please enter your Username: " user -p prompt 提示语
[root@ceshiji ~]#Please enter your Username:
read -s -p "Please enter your Password: " pass -s charaters are notechoed. 字符不回显示。指输入之后,不在回显
cat:显示文件内容,创建文件,还可以用它来显示控制字符
cat file1 file2 file3 同时显示
cat file1 file2 file3>myfile
cat -v dos.txt (-v 显示控制符)
管道|:一个命令的输出传给一个命令的输入
df -k|awk \'{print $1}\'|grep -v \'Filesystem\'
tee:把输出的一个副本输送到标准输出,另一个副本拷贝到相应的文件中。
tee files 在看见输出的同时,也将其存入一个文件。一般用于管道之后。
tee -a files 追加到files中 (-a 表追加)
who|tee who.out
标准输入 0
标准输出 1
标准错误 2
重定向:改变程序运行的输入来源和输出来源。
> >> <<<
command>>filename2>&1
command <filename>filename2
cat file|sort 1 > sort.out 等价于cat file|sort> sort.out
pwd >> file.txt
>nullfile创建一个字节为零的文件 >文件名
sort < file
cat >> aa.txt<< CHINAITLAB把CHINAITLAB结尾的内容都追加到aa.txt
>HELEO ,I AM WANGJIAN
>MY NAME IS $HOME
>bye ...
>CHINAITLAB
重定向标准错误:grep \'test\' file.txt 2>error.txt
grep "test" test.txt>error.txt2>&1 有没有错误都输入到error.txt
exec用来替代当前的shell,并没有启动子shell,而是清楚现有shell环境,重新启动一个shell
exec command
exec ./test.sh exec通常后接一个shell脚本
文件描述符
3-9可以使用 0输入 1输出 2错误
exec 3 <&0 0<name.txt此时不会关闭当前的shell
============================== 控制流结构: if then eles case for until while break continue
if then
elif then
elif then
else
fi
if 条件1
then
语句
elif 条件2 (条件1不成立,执行条件2)
then
else (条件1 2都不成立,执行else)
语句
fi (结束)
?
if语句必须以单词fi终止
if $x=sedsrc;then
echo
then
echo
fi
if [ "10" -lt "12" ]
man test
echo -n "enter your name:"
read NAME
if [ "$NAME" == ""];
then
echo "you did not enter any information"
else
echo "your name is $NAME"
fi
if cp myfile.bak myfile;
then
echo "GOOD COPY"
else
echo "basename $0 :error could not copy the files">&2
=======================case:多选择语句。如果匹配成功,执行匹配的命令
case 值 in
模式1)
命令1
;;
模式2)
命令2
;;
esac
*表任意字符,?表任意单字符 []表范围
echo -n "enter a number from 1 to 3;"
read ANS
case $ANS in
1)
echo "you select 1"
;;
2)
echo "you select 2"
;;
3)
echo "you select 3"
;;
*)
echo "basename $0 :this is not between 1 and 3">&2
;;
esac
case $1 in
get|GET)
create_dir
get_config_file
;;
put|PUT)
put_config_file
;;
stop|STOP)
stop_server
;;
start|START)
start_server
;;
restart|RESTART)
restart_server
;;
*)
echo
echo "$Color_err Useage: ./Configure_squid.shget|put|stop|start|restart $Color_end"
echo
exit 1
;;
esac
========================== for
for 变量 in 列表
do
命令1
命令2
done
for语句 :提供循环执行
使用格式:
for var in values #var是变量 values是一组值
do
语句 #可以是多条语句
done
注意values的值可以全部列出,也可是通配的方式,也可以是某命令的输出值(如$(ls))。
values的值可以是:
1.列表 in 1 2 3 4 5 用空格隔开
2.文件 in file1 file2 file3
3.变量 in $a 命令输出赋值
4.命令 in `ls abc*`
5.字符串表 in "orange red blue gray"
5.特殊: 有时没有in 此时将命令行参数传入
for loop
do
find / -name $loop -print
done
[root@localhost ~]# ./sh match
/root/match
[root@localhost ~]# cat sh
#!/bin/bash
for loop
do
find /root -name $loop -print
done
#!/bin/sh
for ((i = 1; i < 254; i++)) #必须用两个括号
do
arping -I eth0 60.191.82.$i -c 1
done
arp -a > mac_table
?
当变量值在列表里,for循环即执行一次所有命令,使用变量名访问列表中的取值。命令可为任何有效的shell命令和语句。变量名为任意单词。in列表用法是可选的,如果不用它,for循环使用命令行的位置参数。in列表可以包含替换、字符串和文件名。
for((i=1;i<=10;i=i+1))
do
touch ar_$i;
touch full_$i;
done;
for i in {1..100}
do
.......
done
#!/bin/sh
for i in `seq 1 100`
do
echo $i
done
for loop in 1 2 3 4
do
echo $loop
done
for loop in "orange red blue grey"
do
echo $loop
done
for i in $(ls); do du -sh $i; done | sort -n 查看当前目录的大小按小--大排列
======================until
until 条件
do
命令1
命令2
...
done
条件可为任意测试条件,测试发生在循环末尾,因此循环至少执行一次.
read look
until [ "$look" ]
do
echo "full"
done
sleep 1
nohup ./test.sh &
=====================while
while 命令
do
命令1
命令2
...
done
?
??? while [ true ]; do
??? /bin/sleep 1
??? netstat -n | grep 873 >> /usr/local/scripts/873.log
??? done
?
?
$ cat "filelist.txt"
name.txt□
txtf
□a□b□c□
$ while read file; do echo "$file"; done <"filelist.txt"
name.txt
txtf
a□b□c
echo "press ctrl+d ,stop"
while echo -n "enter a file for you like:" ; read film
do
echo " Yeah ,${file} is a good film "
done
while read line
do
echo $line
done<name.txt
break [n]:跳出循环,如果是在一个嵌入循环里,可以指定n来跳出的循环个数
continue:跳过循环步骤(本次循环)
continue只能跳过本次循环。
=====================while :<无限循环,需要加入break跳出>
while:
do
echo -n "enter any number [1...5]"
read ANS
case $ANS in
1|2|3|4|5)
echo "you enter a number between 1 and 5"
;;
*)
echo "wrong number ,bye."
break
;;
esac
done
shift n :参数向左偏移n位。
exit :退出系统
wc -l 查看文件的行数
getopts 多参数传递
ls -R 文件夹 递归查看
iostat 1
umount -a
sync:将缓冲区的内容写到磁盘
r !date :读入日期
r 文件 从文件中读入
!pwd 执行命令 查看当前目录
r !pwd 插入当前目录
文本过滤
正则表达式:由一些字符要(元字符)组成,匹配字符串,过滤所需。
元字符:
^ :只匹配行首 $:只匹配行尾 *:匹配0个或多个此单字符
[]:只匹配[]内字符,可以是一个单字符,也可以是字符列表。可以使用-表示[]内字符序列范围,入用[1-5]代替[12345]
\:只用来屏蔽一个元字符的特殊含义 . 只匹配任意单字符,如...x..x..x
pattern\{n\}:只用来匹配前面pattern出现次数,n为次数
pattern\{n,\}:含义同上,但次数最少为n
pattern\{n,m\}:含义同上,但pattern出现次数在n与m之间.
A\{2\}B:A出现两次 AAB
A\{4,\}B:A最少出现4次,AAAAB AAAAAB
A\{2,4\}B: A出现次数范围2-4次
[0-9]\{3\}\.[0-9]\{3\}\.[0-9]\{3\}\.[0-9]\{3\}匹配ip地址
^:只允许在一行的开始匹配字符或单词.
^d
drwxrwxrw- 匹配 -rwx--x--x 不匹配
^...1
3351xc 匹配 338xcd 不匹配
$:与^相反,只允许在行尾匹配字符或字符串
trouble$
^$ :匹配空行 ^.$:匹配包含一个字符的行
*:匹配任意字符包括零个字符 如300*2 3002 匹配
\:屏蔽一个特殊字符 如* $ .
\*\.pas:匹配以*.pas结尾的所有字符或文件.
[]:匹配一个范围或集合 ,用逗号分开. 用-表示范围
[0-9] [a-z] [A-Z a-z 0-9] [S,s]
find:用来查找具有某些特征的文件的命令.遍历大的文件系统时,一般放在后台运行.
find path -options [-print -exec -ok]
-print 输出到标准输出
-exec 对匹配的文件执行该参数所给出的shell命令 形式为 command {} \; 注意{}和\;之间有空格
find . -type f -exec ls -l {} \;
find . -name "*.log" -mtime +5 rm {} \;
有时参数太长或参数列溢出,此时要用xargs 类似与exec
find / -perm -7 -print |xargs chmod o-w
find / -type f -print |xargs file
-ok 和-exec作用相同,只不过-ok以一种更安全的方式运行.
-options:
-name文件名 文件名要引号
find ./ -name "aa.txt" -print
find ./ -name "[A-Z]*" -print 大写开头的
-perm文件权限
find -perm 755 -print (路径没有表示为当前目录)
-user文件的属主
find `pwd` -user root -print
-group 文件的属组
find ./ -group root -print
-atime ctime mtime -n +n -n表示文件更改距现在n天以内(之内),+n表示文件更改时间距现在n天以前
find 、-mtime -5 -print 修改在5天内的文件
-size n[c] 查找文件长度为n块的文件,带有c表示文件长度以字节计算
find . -size +1000000c -print 大于1000000c字节的文件
find . -size -100 小于100块的文件
-type 类型 b p c f(普通文件)
-nouser -nogroup 无属主,属组的文件 ,删除用户时产生
find / -nouser -print
find / -newer "myfile" !-newer "yourfile" -print查找比文件myfile新比yourfile旧的文件
-depth 在子目录中查找
find . -name "aa.txt" -depth -print
grep 对文本文件进行模式查找
grep "jeny" *.txt
grep -c (只输出匹配的行数)
grep -c "aa" aa.txt
grep -n (显示匹配的行和行号)
grep -i (忽略大小写)
grep -v (反向查找)
grep -h (查询多文件时不显示文件名)
grep -H (显示文件名)
grep -s (不显示不存在或无匹配文本的错误信息)
grep "2004:22:5[0-9]" aa.txt
grep "^[^210]" myfile 不显示是210的行:包括2、1、0 打头的行
grep "\?" aa.tet 查找?
grep "[0-9]\{1,3\}.[0-9]\{1,3\}.[0-9]\{1,3\}.[0-9]\{1,3\}"qshengyang12.xml 过滤除ip地址
grep "[0-9 A-Z]\{2\}:[0-9 A-Z]\{2\}:[0-9 A-Z]\{2\}:[0-9A-Z]\{2\}:[0-9 A-Z]\{2\}:[0-9 A-Z]\{2\}"qshengzheng12.xml过滤mac地址
grep的命令类别
[[:upper:]] 等价于[A-Z]
[[:alnum:]] 等价于[0-9 a-z A-Z]
[[:lower:]] 等价于[a-z]
[[:space:]] 等价于空格或tab键
[[:digit:]] 等价于[0-9]
[[:alpha:]] 等价于[A-Z]
service dhcpd start > /dev/null 不显示
grep "5[[:digit:]][[:digit:]]" file 在file中查找500 到599
nmap -sT ip地址
arping ip 地址
awk:是一种自解释的编程语言,可从文件或字符串中基于指定规则浏览和抽取信息。
awk脚本由各种操作和模式组成
模式和动作
模式部分决定动作语句何时触发及触发事件。(BEGIN,END)
动作对数据进行处理,放在大括号{} 内指明。(print)
分隔符号、域和记录
awk执行时,其浏览域标记为$1,$2....$n。这种方法称为域标识。$0为所有域。
注意执行时不要混淆符号$和shell提示符$,它们是不同的。
三种方式调用awk
命令方式:awk [-F filed-spearator] \'command\' input-files 用单引号 -F来指定分隔符如 -F :
awk脚本:脚本文件
awk命令插入一个单独文件: awk -f awk-script-file input-files
awk中的$跟shell中不含义不同 $0 是所有域,$1是第一个域 ,$2是第二个域....
awk \'{print $0}\' score.txt 按行打印文件score.txt的各行.即打印所有域。
awk -F : \'{print $0}\' score.txt默认分隔符是空格,可以用-F 来指定 本例子是:
awk \'{print $1 "\t" $3}\' score.txt 打印显示第1和第3个域
awk \'BEGIN {print "num ip/n-----"} {print $1 "\t" $4} END {print"end-of-report"}\' ab.txt BEGIN和END定义了报头 num ip打印显示第1和第4个域,最后显示end-of-report
num ip
-----
64 172.0.0.1
函数定义:shell允许将一组命名集或语句形成一个可用块,这些块称为shell函数
格式:
函数名()
{
命令1
...
}
function 函数名()
{
....
}
定义函数
#!/bin/bash
function hello ()
{
echo "hello ,today is `date`"
return 1
}
echo "this is a function test"
hello
调用:直接输入函数名
hello
参数传递到函数中
向函数传递参数就像在脚本中使用位置变量$1,$2,$3....$9
#!/bin/bash
function hello ()
{
echo "hello ,$1 today is `date`"
return 1
}
echo "this is a function test"
hello wangjian
显示: hello ,wangjian says: today is Fri Oct 12 18:05:25 csT2007
函数文件
文件1:
#!/bin/bash
.hellofun #调入函数hellofun
echo "now going to the function hello"
hello
echo "back from the function"
文件2:
#!/bin/bash
function hello ()
{
echo "hello, today is `date`"
return 1
}
>文件名:创建大小为0的空文件
查看载入函数:set
文件1:
#!/bin/bash
.hellofun #调入函数hellofun
set
echo "now going to the function hello"
hello
echo "back from the function"
文件2:
#!/bin/bash
function hello ()
{
echo "hello, today is `date`"
return 1
}
删除函数:unset
文件1:
#!/bin/bash
.hellofun #调入函数hellofun
unset
echo "now going to the function hello"
hello
echo "back from the function"
文件2:
#!/bin/bash
function hello ()
{
echo "hello, today is `date`"
return 1
}
函数返回值:返回return的值 return 是何值就是何值。
文件1:
#!/bin/bash
.hellofun #调入函数hellofun
unset
echo "now going to the function hello"
hello
echo $?
echo "back from the function"
文件2:
#!/bin/bash
function hello ()
{
echo "hello, today is `date`"
return 1
}
awk深入学习
awk中特殊元字符 :+:表任意字符 ?:表单个字符
匹配操作符:~:匹配 !~:表示不匹配 使用:~/匹配内容/
cat score.txt|awk \'$0~/218.79.131.96/\'
awk \'$0 !~/218.79.131.96/\' score.txt
awk \'{if ($1=="218.79.131.96") print $0}\' score.txt
man awk
sed介绍
sed 选项 命令(\'\') 文件
sed不与初始化文件打交道,它操作的只是一个拷贝,然后所有的改动如果没有重定向到一个为文件,将输出到屏幕。
sed是一种重要的文本过滤工具,使用一行命令或者使用管道与grep与awk相结合
非交互性文本流编辑。
调用sed有三种方式
使用sed命令行格式为:sed [选项] sed命令 输入文件 命令用\'\'刮起来
使用sed 脚本文件,格式:sed [选项] -f sed 脚本文件 输入文件
sed脚本文件 [选项] 输入文件
不管是使用shell命令行方式或脚本文件方式,如果没有指定输入文件,sed从标准输入中接受输入,一般是键盘或重定向结果。
sed命令选项
n 不打印没匹配的
c 下一命令是编辑命令
f 正在调用sed脚本文件
sed 在文件中查询文本的方式
使用行号,可以是一个简单数字,或者是一个行号范围。
使用正则表达式
x 为一行号
x,y 表示行号范围从x到y
/pattern/ 查询包含模式的行
/pattern/pattern/ 查询包含两个模式的行
pattern/,x 在给定的行号上查询包含模式的行
x,/pattern/ 通过行号和模式查询匹配行 (从x行匹配到/pattern结束)
x,y! 查询不包含指定行号x和y的行
基本sed编辑命令
p:打印匹配行
=:显示文件行号
a\:在定位行号后附加新文本信息后面(分两行写)
i\:在定位行号后插入新文本信息前(分两行写)
d:删除定位行
c\:用新文本替换定位文本
s:使用替换模式替换相应模式
r:从另一个文件中读文件
w:写文本到一个文件
q:第一个模式匹配完成后推出或立即推出
l:显示与八进制ascii代码等价的控制字符
{} 在定位行执行的命令组
n 从另一个文件中读文本下一行,并附加在下一行
g 将模式2粘贴到/pattern n/
y 传送字符
例子:
sed \'2p\' aa.txt 打印第2行(其他也打印)
sed -n \'2p\' aa.txt 只打印第二行
sed -n \'1,4p\' aa.txt 只显示1-4行
sed -n \'/los/p\' aa.txt 只显示 含有los的行
sed -n \'4,/los/p\' aa.txt 只显示从第四行开始知道匹配到los为止的之间所有行
sed -n \'/^$/=\' aa.txt 只显示空行
sed -n -e \'/^$/p\' -e \'/^$/=\' aa.txt 只显示空行和空行行号 (-e表示多命令同时执行)
sed -n \'/beijing/a\/shenzhen/\' aa.txt在beijing所在行的下一行追加shenzhen(命令从/shenzhen/\' aa.txt换行(不改变aa)输入)
sed -n \'/beijing/i\/shenzhen/\' aa.txt在beijing所在行的前一行插入shenzhen(命令从/shenzhen/\' aa.txt换行输入)不改变aa,但可以重定到一个文件中改变原文件)
sed -n \'/beijing/c\/shenzhen/\' aa.txt将beijing所在行替换shenzhen(命令从/shenzhen/\' aa.txt换行输入)(不改变aa,但可以重定到一个文件中改变原文件)
sed \'1,2d\' aa.txt 删除1和2行
sed \'s/beijing/shanghai/g\' aa.txt
sed -n \'s/china/&hello/p\' aa.txt在匹配到china字符后追加hello
sed -n \'s/china/hello &/p\'aa.txt在匹配到china字符前追加hello
sed \'1r bb.txt\' aa.txt 在aa.txt的第一行下面插入bb.txtwenjian
sed \'/china/q\' aa.txt 匹配到第一个china就退出
sed -n \'/china/l\' aa.txt 以八进制显示
info sed man sed
sed \'/m/G\' 文件名搜索到回车加一个空行
awk \'/from/{print}\' 名打印所有含有from的行
-------------------------合并与分隔
sort 选项 files
许多不同的域按不同的列顺序分类
-c 测试文件是否已经分类
-m合并两个分类文件
-u删除所有复制行
-o 存储sort 结果的输出文件名
-t 域分隔符;用非空格或tab键分隔域
+n n为域号,使用此域号开始分类
n指定分类是域上的数字类项
-r 比较求逆
man sort
sort -c aa.txt
sort -u aa.txt 合并,有重复的行只显示第一个
sort -r aa.txt 求逆,从下向上排序
sort -t "." +2 aa.txt 分隔符为. 对第2个域进行ASCII码排序 域号从0 1 2 ..
sort -t "." +2n aa.txt 分隔符为. 对第2个域进行数字排序 域号从0 1 2 ..
-----------------------uniq 选项 file
从一个文本文件中去除或禁止重复的行
-u 只先显示不重复的行
-d 只显示有重复的数据行,每种重复行只显示一行
-c 打印每一重复行出现次数
-fn n为数字,前n个域被忽略,只比较后面
man uniq
uniq -c file 查看重复次数(这里重复指的是相邻重复,隔行重复不算)
uniq -d file 只显示有重复的数据行,每种重复行只显示一行(相邻重复,隔行重复不算)
uniq -f 2 myfile.txt 前2个域被忽略,从后面的域比较
uniq -d
sort aa.txt|uniq -c 等价于 sort -u aa.txt查看重复次数(这里重复指的是相邻重复和隔行重复)
深入讨论awk
条件操作符
~:匹配正则表达式
!~:不匹配正则表达式
&&:and
||:or
!:not
awk \'{if ($1~/^4/) print $0}\' file如果文件file中第一个域匹配是4开头的行就全部显示
awk \'{if ($1!~/^4/) print $0}\' file如果文件file中第一个域匹配不是4开头的行就全部显示
awk \'{if ($4~/^\[07\/jul\/2004/) print $0}\' file打印是[07/jul/2004]开头的所有行
--------------------------awk内置变量
ARGC 命令行参数个数
ARGV 命令行参数排列
ENVIRON 支持队列中系统环境变量的使用
FILENAME awk 浏览的文件名
FNR 浏览文件的记录数
FS 设置输入域分隔符,等价于命令-F选项。
NF 浏览文件域的个数
NR 已度的记录数(行数)
OFS 输出域分隔符
ORS 输出记录分隔符
RS 控制记录分隔符
文件aa的内容为
ab#slfjslk
cd#fslkjf
df#123fjls
eb#j9sq
op#9sjtr
awk -F \'#\' \'{print NR,NF,$0}\' aa 打印行数 域数 所有记录
awk -F \'#\' \'{print ENVIRON["USER"],FILENAME, $0 ARG ARGV[0]}\'aa 打印USER环境变量,文件名,所有记录,参数个数,第一个参数。
--------------------------------字符串函数
gsub(r,s) 在整个$0中用s替代r
gsub(r,s,t)在整个t(域或记录)中s替换r
index(s,t)返回s中字符串t的第一位置
length(s)返回s的长度
match(s,r)测试s中是否包含匹配r字符串
split(s,a,fs)用fs域上将s分成序列a
sprint(fmt,exp)返回经fmt格式化后的exp
sub(r,s) 用$0中最左边最长的子串代替s
substr(s,p) 返回字符串s中从p开始的后部分
substr(s,p,n) 返回字符串s中从p开始长度为n的后部分
awk -F \'#\' \'{if(gsub("s","S",$1)) print $1}\' aa.txt替换文件aa.txt的$1中s变成S
awk -F \'#\' \'{if(gsub("s","S")) print $0}\' aa.txt 默认是$0
awk -F \'#\' \'{print(index($2,"s")) }\' aa.txt打印$2中s字符所在的位置。(注意是字串在前)
awk 转义字符
\b 退格键
\t tab键
\f 走纸换页
\ddd 八进制值
\n 新行
\c 任意其他特殊字符,例如\\为反斜线符号
\r 回车符
awk -F \'#\' \'{print(index($2,"s"),"\t" ,$2) }\' aa.txt
?
?
-------------------------------- printf修饰符
%c ASCII字符
%d 整数
%f 浮点数,例如(123.44)
%e 浮点数,科学记数法
%f 新行
%g awk 决定使用哪种浮点数转换e或者f
%o 八进制数
%s 字符串
%x 十六进制数
awk 数组
awk \'BEGIN {print split ("as*123",array2,"*")}\'
./awk_arry.sh grade.txt
##############
# main menu()#
##############
curdate=`date "+%Y-%m-%d %T"`
date "+%Y-%m-%d %T"显示当前日期和时间
case $a in
7)
exit
;;
*)
clear
continue
;;
esac
?
?