一:基本命令部分
查找系统中所有文件长度为0的普通文件,并列出它们的完整路径;
/
示系统所有文件 如果空白表示当前目录
f : 一般档案,普通文件
-exec <命令或脚本> {} \ 对查询结果转给其他命令操作
ls -l 列出详细信息
查找/zsh目录中更改时间在7日以前的普通文件,并在删除之前询问它们;
$ find zsh -type f -mtime +7 -ok rm { } \;
解释:-mtime n 查找系统最后n*24小时被改变文件数据的文件。
3、myfile.html内容如下:
This is what
I meant.
删除HTML标记,也就是要得到:
This is what I meant.
cat myfile.html| sed 's/
//g;s/<\/b>//g'
解析:s///g 将文件含有的字符转换为空字串,
s/<\/b>//g 将文件含有<\b>的字符转换为空字符,\转定义字符,将特殊符号意义去除。
g 表示全局化处理,没加g的话 只会替换一行里的第一个然后就替换下一行了
使用tr命令将指定文件的空行删除
tr -s ['\n']标准输入的字符)
tr 转换字符,例如:将大写字符转换成小写字符。选项可以让你指定所要删除的字符,以及将一串重复出现的字符浓缩成一个。
-s删除所有重复出现字符序列,只保留第一个;即将重复出现字符串压缩为一个字符串。
在txt目录下搜索所有包含有‘the’单词的.c文件,列出文件名
grep -lr "the" *.c
-l打印匹配模板的文件清单
-r递归地搜索目录。在缺省情况下,按照到目录的链接。
使用grep将express文件里以数字开头的行删除掉
grep '^[^0-9]' express
^[0-9] 代表查找的字符是数字且放在行首
[^] 匹配一个不在指定范围内的字符
^[^0-9] 代表以不以数字开头的行
让电脑10秒钟后重启
shutdown -r +10 (这是10分钟)
sleep 10 ; shutdown -r now
在shell执行命令时,屏蔽掉错误信息。
2>/dev/null
2表示错误的信息, /dev/null 垃圾箱,表示把错误的信息直接输出到垃圾箱,即删除
解释命令:trap ‘echo hello int’ INT。
trap是一个shell内建命令,它用来在脚本中指定信号如何处理。比如,按Ctrl+C会使脚本终止执行,实际上系统发送了SIGINT信号给脚本进程,SIGINT信号的默认处理方式就是退出程序。如果要在Ctrl+C不退出程序,那么就得使用trap命令来指定一下SIGINT的处理方式了。trap命令不仅仅处理Linux信号,还能对脚本退出(EXIT)、调试(DEBUG)、错误(ERR)、返回(RETURN)等情况指定处理方式。
Trap “ “ INT 表示忽略SIGINT信号,按Ctrl+C不会退出脚本 ,输出”hello int”
通常我们需要忽略的信号有四个,即:HUP, INT, QUIT, TSTP,也就是信号1, 2, 3, 24
当您运行Ctrl+C 等中断时,会自动运行echo命令
INT:中断信号,通常因按下Ctrl+C组合键而引发
10,强制结束指定进程号的进程
kill -9 pid
(pid为指定的进程号)
11,将某个文件的属性更改为只有root可读写执行。
chown root filename
chmod 700 filename
查出系统中所有用户标识号大于99的用户
cat /etc/passwd | awk -F ':' '{if ($3>99) print $1}'
统计系统中用户标识号大于99的用户数
cut -d: -f 1,3 /etc/passwd |grep '[0-9]\{3,\}' | wc -l
cut命令有5个参数,其中-c,-b,-f分别表示"character", "byte"以及"field"截取方式。
当采用field模式截取时,需要用"-d"参数指定一个分隔符,分割符只能为单个字符。
cut -d: -f 1,3 /etc/passwd 在/etc/passwd中以“:”为分隔符,取出第1和第3的域
grep '[0-9]\{3,\}' 0-9任何一个数字重复三遍
Wc -l 统计文件行数
(cut -d: -f 3 /etc/passwd |grep '[0-9]\{3,\}' | wc -l 也行)
14 .按文件大小的降序列出目录中的所有文件
ls -l | sort -nrk 5
将当前目录下的所有文件打包成一个文件。
tar czvf 名字.tar.gz $(ls)
也可以 tar czvf 名字.tar.gz . (最后面的小数点. 表示当前目录)
关于tar命令:
-c :建立一个压缩文件的参数指令(create 的意思);
-z :是否同时具有 gzip 的属性?亦即是否需要用 gzip 压缩?
-v :压缩的过程中显示文件!这个常用,但不建议用在背景执行过程!
-f :使用档名,请留意,在 f 之后要立即接档名喔!不要再加参数!
解释命令: ln a b
ln是linux中又一个非常重要命令,它的功能是为某一个文件在另外一个位置建立一个同不的链接。
ln –s 源文件 目标文件 :为a生成一个软连接b,软连接,不占磁盘空间。
ln 源文件 目标文件 :为a生成一个硬连接b, hard link 占磁盘空间。
用命令方式将一个进程暂停
kill -STOP pid(pid为进程号)
解释命令 :find -name hello.c -exec ls -l {} \;
查找当前目录中所有的hello.c文件并列出他们的详细信息
(the.c为例)
解释命令:grep –n ‘^[^a-zA-Z]’ express
输出express 文件中不以字母开头的行, -n 显示行号
解释命令:grep –v ‘^$’ express | grep –v ‘^#’
-v:反向选择
‘^$’ :以$结尾开头,即表示空行
‘^#’:以为#号开头
显示express中的非空行和非#号开头的句子
解释命令:grep –n ‘o\{2\}’ express
输出含有两个o的句子
解释命令:grep –n ‘^\(.\).*\1$’ express
匹配一行中头一个字符跟最后一个字符相同的行
解释命令: cat -n express | sed 'd;n'
读一行,删一行,读一行,显示出来是空的;
注意”执行n时会首先输出当前处理行
解释命令:cat -n express | sed -n 'p;N'
cat的-n是输出行号
sed的-n 取消默认输出
p 输出
N追加一行
输出奇数行
解释命令:cat -n express | sed -n 'N;p'
-n 取消默认输出
p 输出
N追加一行
偶数行就全部输出
奇数行就最后一行不输出
解释命令:sed = express | sed 'N;s/\n/:/'
= 号 :打印当前的行号
sed = express的输出是:
N追加一行
s替换
\n是换行符
s/\n/: 把换行符换成冒号
解释命令:sed '$!N;/^\(.*\)\n\1$/!P;D' chongfu
P:打印模板块的第一行
D:删除模式空间开头到第一个\n(含)之间的内容,并且控制流跳到脚本的第一条语句
删除重复行后输出
解释:$!N:如果不是结尾行,则追加下一行到模板区,在两者间加上\n。
/^\(.*\)\n\1$/!P:如果本行跟模板空间中的内容相同。
注意:执行D命令之后,模板块内不添加下一笔数据, 而将剩下的数据重新执行sedscript 。也就是直接再次执行N命令,读入下一行,然后删除第一行。一直这样循环,直到最后一行,打印输出模板块中的内容,也就是最后一行的内容
解释命令:sed -e '1!G;h;$!d' express
-e 表示允许多次修改
! :表示后面的命令对所有没有被选定的行发生作用。(非)
G:获得内存缓冲区的内容,并追加到当前模板块文本的后面。
h: 拷贝模板块的内容到内存中的缓冲区。(覆盖)
d:从模板块位置删除行。(删除整个模板快)
文件倒着输出
29.解释命令:echo "WeLoveChinaUnix"|sed -e 'H;s/\(..\).*/\1/;x;s/.*\(.\{9\}\)$/\1/;x;G;s/\n/ /'
H: 追加模板块的内容到内存中的缓冲区。
s:替换
x表示互换模板块中的文本和缓冲区中的文本。
G:获得内存缓冲区的内容,并追加到当前模板块文本的后面。
\n是换行符
s/\(..\).*/\1/; 前两个字符
s/.*\(.\{9\}\)$/\1/; 后九个字符
s/\n/ /; 换行符替换成空格
所以输出 We ChinaUnix
二:分别使用sed和awk实现下面的功能(使用express文件)
在每一行后面增加一空行
sed G express
G:获得内存缓冲区的内容,并追加到当前模板块文本的后面。 (此时缓冲区是空白行)
awk '{print $0 "\n"}' express
设置文本中每一行后面有且只有一空行。
sed '/^$/d;G' express
/^$/d; 表示遇到空行就删除
G:获得内存缓冲区的内容,并追加到当前模板块文本的后面。 (此时缓冲区是空白行)
awk '!/^$/{printf("%s\n\n",$0)}' express
!/^$/ 表示不是空行
printf("%s\n\n",$0) 输出正行数据并两个换行符,即一个空行
在每行后面增加2行空行
sed '/^$/d;G;G' express
awk '!/^$/{printf("%s\n\n\n",$0)}' express
删除所有偶数行
sed 'n;d' express
sed ‘n;d’ 执行n时会首先输出当前处理行,然后读取下一行,并使用d命令删除。
在匹配The的行前插入空行
sed ‘/The/ {x;p;x}’ express
awk ‘if(/The/) printf(“/n%s/n”,$0);else print $0 ’ express
输出行号,行号和正文间加冒号
sed = express | sed 'N;s/\n/:/'
sed相关命令参数:
N:追加下一个输入行到模式空间后面并在二者间嵌入一个
“\n”,改变当前行号码。
=:打印当前行号
awk '{printf("%d:%s\n",NR,$0)}' express
%d:十进制有符号整数
NR:行号
对文件中的所有非空行编号
计算行号(模拟 “wc -l”)
sed -n '$=' express
关于WC命令:
wc就是word count(数字数)的缩写,通常利用Linux的wc命令和其他命令结合来计算行和其他信息。在Linux下用wc进行计数。返回文件的行数、字数、字节数等。
wc -m filename:显示一个文件的字符数
wc -l filename:显示一个文件的行数
wc -L filename:显示一个文件中的最长行的长度
wc -w filename:显示一个文件的字数
sed相关的命令参数:
-n, --quiet, --silent
安静模式,取消默认输出。
$:锚定行的结束 如:/sed$/匹配所有以sed结尾的行。
=:打印当前行号
相关解释:
$=表示打印最后一行的行号,-n表示安静模式,不会输出其他行的相关内容
awk 'END {print NR}' express
awk相关的知识点:
BEGIN和END
在awk 中两个特别的表达式,BEGIN和END,这两者都可用于pattern中,提供BEGIN和END的作用是给程序赋予初始状态和在程序结束之后执行一些扫尾的工作。任何在BEGIN之后列出的操作(在{}内)将在awk开始扫描输入之前执行,而END之后列出的操作将在扫描完全部的输入之后执行。因此,通常使用BEGIN来显示变量和预置(初始化)变量,使用END来输出最终结果。
所以awk 'END {print NR}'也就是在读取到最后一行之后,才输出对于的行号,也就是输出该文件的行数。
模拟dos2unix
实现dos2unix的关键就是把dos中多余的\r去掉。
sed 's/\r//g' expressdos >expressdos1
模拟unix2dos:
sed 's/$/\r/' expressdos > expressdos1
或
sed 's/$/\x0d/' expressdos >expressdos1
awk 'gsub(/\r/,""){print $0}' express > express2
gsub(r,s,t):在字符串t中用字符串s和正则表达式r匹配的所有字符串替换。返回值是替换的个数。如果没有给出t,默认是$0
相关解释:
使用gsub把\r替换成"",然后再输出当前处理的整行字符串
将所有good改为bad并打印且只打印该行
sed -n ‘s/good/bad/g p’ express
awk 'gsub("good","bad"){print $0}' express
将包含is的行的good改为bad并打印且只打印该行
sed -n '/is/{/good/{s/good/bad/g;p}}' express
-n:安静模式,取消默认输出。
g:表示行内全面替换,当前处理行进行全局替换。
-n使用安静模式,/is/匹配包含is的行,/good/匹配包含is的行中包含good的行,s/good/bad/g,把改行所有的good都替换成bad,然后使用p输出该行。
awk '{if ($0~/is/ && $0~/good/) {gsub(“good”,"bad"); print $0}}' express
$0~/is/表示使用第0个域匹配/is/正则表达式,第0个域保存的即是当前处理的整行数据。
($0~/is/ && $0~/good/)就是如果当前处理的整行同时包含is和good的话就执行if里面的语句。if里面的语句使用gsub把匹配的good替换成bad,然后输出当前行。
将不包含is的行的good改为bad并打印且只打印该行
sed -n ‘/is/! {/good/{s/good/bad/g;p}}’ express
awk '{if ($0!~/is/ && $0~/good/) {gsub(/good/,"bad"); print $0}}' express
显示文件中的前10行 (模拟“head” )
sed 10q express
q表示退出sed,10q表示处理到第10行的时候退出sed。
awk '{if (NR<11) print $0}' express
NR:表示awk开始执行程序后所读取的数据行数
在每5行后增加一空白行
sed 'n;n;n;n;G' express
n :读取下一个输入行,用下一个命令处理新的行而不是用第个命令。
G:获得内存缓冲区(hold space)的内容,并追加到当前模式空间文本的后面。
n;n;n;n;G的执行4个n命令读取下一行,每次读取之前都先输出当前的处理行。然后把hold space(这时为空)中的内容追加到模式空间的后面,相当于增加一空白行。
awk '{if (NR%5!=0) print $0;else printf("%s\n\n",$0)}' express
倒置所有行,第一行成为最后一行,依次类推(模拟“tac”)
关于tac命令:
把文件内容反过来显示,文件内容的最后一行先显示,第一行最后显示。
sed '1!G;h;$!d' express
G:获得内存缓冲区的内容,并追加到当前模板块文本的后面。
h:拷贝模板块的内容到内存中的缓冲区。
d :从模板块(Pattern space)位置删除行。
!:表示后面的命令对所有没有被选定的行发生作用。
$:锚定行的结束 如:/sed$/匹配所有以sed结尾的行。这里表示文件最后一行。
1:表示文件第一行
第一行的时候
1!G:在处理第一行的时候不把缓冲内容添加到 当前处理行的末尾(因为你处理第一行的时候,缓冲还为空呢)
h:这个时候把第一行的内容(1)放到缓冲区
$!d:因为不是最后一行,所以删除,不打印出来
第二行的时候
1!G:此时1!G成立,把上一次保存的缓冲区内容(1)放到当前行(2)的末尾,第二行变成了(21)
h:这个时候把第二行的内容(21)放到缓冲区
$!d:因为不是最后一行,所以删除,不打印出来
第三行的时候
1!G:因为是第三行,所以1!G成立,则把上一次(第二行)保存的缓冲区内容(21)放到当前行(3)的末尾,第二行变成了(321)
h:这个时候把第三行的内容(321)放到缓冲区
$!d:因为不是最后一行,所以删除,不打印出来
这样直到处理到最后一行的时候:
1!G:此时1!G成立,把上(n-1)一次保存的缓冲区内容([n-1]…321)放到当前行(n)的末尾,该行变成了(n…321)
h:这个时候把第n行的内容(n…321)放到缓冲区
$!d:因为是最后一行,所以不删除,打印出第六行内容 n[n-1]…321
awk '{A[i++]=$0}END{for(j=i-1;j>=0;j--)print A[j]}' express
BEGIN和END
在awk 中两个特别的表达式,BEGIN和END,这两者都可用于pattern中,提供BEGIN和END的作用是给程序赋予初始状态和在程序结束之后执行一些扫尾的工作。任何在BEGIN之后列出的操作(在{}内)将在awk开始扫描输入之前执行,而END之后列出的操作将在扫描完全部的输入之后执行。因此,通常使用BEGIN来显示变量和预置(初始化)变量,使用END来输出最终结果。
首先输入每行字都执行A[i++]=$0,即是把所有行的内容保存到A[i]数组中。直到处理完所有的行之后,继续质询END中的内容:for(j=i-1;j>=0;j--)print A[j],这里是吧A[i]中的元素倒序输出,即是倒置所有的行。
显示文件中的最后10行 (模拟“tail”)
sed方法:
sed -e :a -e '$q;N;11,$D;ba' express
sed方法相关命令参数:
-e
直接在指令列模式上进行 sed 的动作编辑,允许多台编辑。
:a
表示建立一个标签a
b
跳转命令,这个命令是无条件跳转
ba表示跳转到标签a处
q
退出Sed。
N
追加下一个输入行到模板块后面并在二者间嵌入一个“\n”,改变当前行号码。
D
删除模板块的第一行。
11
表示文件第十一行
相关解释9:
首先创建一个a标签,然后不断执行这段代码:$q;N;11,$D;ba,如果是最后一行则退出sed,否则继续循环,N读取下一行,读取模式空间的第11行,如果是最后一行则删除模式空间的第一行,继续跳到标签a处执行。
awk方法:
awk '{a[i++]=$0}END{if (i>10) for (j=i-10;j
10),如果是则输入最后10个元素,否则直接输出所有的元素。
显示文件中的最后2行(模拟“tail -2”命令)
关于tail命令:
tail [ -r ] [ -n Number ] [ File ]
tail 命令从指定点开始将 File 参数指定的文件写到标准输出。如果没有指定文件,则会使用标准输入。 Number 变量
指定将多少单元写入标准输出。 Number 变量的值可以是正的或负的整数。如果值的前面有 +(加号),从文件开头
指定的单元数开始将文件写到标准输出。如果值的前面有 -(减号),则从文件末尾指定的单元数开始将文件写到
标准输出。如果值前面没有 +(加号)或 -(减号),那么从文件末尾指定的单元号开始读取文件。
tail -2即是输出最后两行。
sed方法:
sed '$!N;$!D' express
sed相关命令参数:
!
表示后面的命令对所有没有被选定的行发生作用。
N
追加下一个输入行到模板块后面并在二者间嵌入一个“\n”,改变当前行号码。
D
删除模板块的第一行。
相关解释:
$!表示如果不是最后一行则执行N命令追加下一行,$!D表示如果不是最后一行则删除第一行。注意:执行D命令之后,pattern space 内不添加下一笔数据, 而将剩下的数据重新执行sedscript 。也就是直接再次执行$!N命令,读入下一行。知道最后一行时就不执行D删除命令,此时patten space中有最后两行数据。
awk方法:
awk '{a[i++]=$0}END{if (i>2) for (j=i-2;j=50) print $0}' express
显示部分文本——从包含apple的行开始到最后一行结束
sed -n '/apple/,$p' express
awk 'BEGIN{p=1}{if ($0~/apple/ || p==0){p=0;print $0}}' express
显示通篇文档,除了从包含apple的行到包含google的行
sed '/apple/,/google/d' express
/apple/,/google/d表示匹配从包含apple的行到包含google的行,然后使用d全部删除。
awk 'BEGIN{p=1}{if ($0!~/apple/ && p==1)print $0;else p=0;if ($0~/google/) p=1;}' express
首先在BEGIN中给p赋初值1,然后依次处理每一条语句。如果没有匹配到apple并且p==1,则输出改行;否则p=0,直到匹配到google为止,才让p=1,继续输出
三 shell部分
编写一个名为nf的程序,显示当前目录中的文件数。键入程序并测试。
ls | awk ‘{files++} END {print files}’
编写一个名为whos的程序,显示排好序的已登录用户清单。只显示用户名,不要有其他信息。键入程序并测试。
who | sort -nrk1 | awk '{print $1}'
-n按照数字方式排序。
-r 颠倒指定排序的顺序。
-k作用是根据某个列来排序,默认是第1列(从1开始)。
54.在终端上显示
<<< echo $x >>> displays the value of x,which is $x
显示的时候,第2个$x的值应该被替换,比如如果x=3,显示:
<<< echo $x >>> displays the value of x,which is 3
X=3
echo "<<< echo \$x >>> displays the value of x,which is $x"
55.依次执行下面三条命令,分析结果。
filename=/home/zsh/express
filename=$(echo $filename | tr “$(echo $filename | cut –cl)” “^”)
echo filename
如果是echo $filename则输出结果: ^home^zsh^express
但是这里filename只是一个字符串,所以echo filename就只是输出filename这个字符串
-c1表示取出第一个字符
$(echo $filename | cut –cl) 表示取文件名的第一个字符的值,即“/”
tr “$(echo $filename | cut –cl)” “^” 表示把每一个“/”都替换成“^”
shell编程里的$(…)结构是什么作用,举例说明。
编写一脚本,打印出所有的参数。
#!/bin/sh
echo they are $*
exit 0
#! /bin/sh 是指此脚本使用/bin/sh来解释执行,#!是特殊的表示符,其后面跟的是解释此脚本的shell的路径)如果没有声明,则脚本将在默认的shell中执行,默认shell是由用户所在的系统定义为执行shell脚本的shell.
编写一个脚本,统计参数的总数。
#!/bin/sh
echo "$#"
exit 0
编写一个脚本,判断指定的文件是否存在
if [ ! -e “$1” ] ;then
echo “$1 do not exist”
fi
-e 当指定的文件或目录存在时返回真
-e 当指定的文件或目录存在时返回真
60. 编写一个名为rename的程序,给第1个参数所给定的文件更名,在原名后添加第2个参数包含的一串字符。即
rename memol .sv
应该将文件memol更名为memol.sv
创建一个rename的文件,在里面编写:
mv $1 $1$2
mv $1 $1$2,中$1对应第一个参数,$2对应第二个参数,即是把$1对应的文件名更改为由$1$2组成的文件名
61.编写一个名为unrename的程序,从第1个参数指定的文件名的后部去掉第2个参数包含的字符串,即
unrename memol.sv .sv
应该把文件memol.sv更名为memol。要保证从尾部去掉字 符串,如
unrename test1test test
应该将tes1test更名为test1(提示:用sed和命令替换)
mv $1 $(echo $1 | sed "s/$2$//")
$2$表示匹配第二个域的内容直到结尾的
编写一个shell脚本,使用循环语句将当前目录下的.c文件更名为.cpp.
解决方法:
for loop in $(ls)
do
if echo "$loop" | grep -q '\.c'
then
mv $loop $(echo $loop | sed "s/\.c$/\.cpp/")
fi
done
关于shell脚本的for循环语句:
for循环语句格式如下:
for 变量名 in 取值列表
do
命令列表
done
相关解释:
for loop in $(ls)表示变量loop从ls命令得到的列表中取值。
if echo "$loop" | grep -q '\.c'中-q或--quiet或--silent 表示不显示任何信息。整句表示判断是否找到以.c结尾的文件,找到则执行then里面的语句。
mv $loop $(echo $loop|sed "s/\.c$/\.cpp/")表示把.c换成.cpp
source命令和exec命令有啥区别?举例说明。
exec和source都属于bash内部命令(builtins commands),在bash下输入man exec或man source可以查看所有的内部命令信息。
shell的内建命令exec将并不启动新的shell,而是用要被执行命令替换当前的shell进程,并且将老进程的环境清理掉,而且exec命令后的其它命令将不再执行
source命令或者".",不会为脚本新建shell,而只是将脚本包含的命令在当前shell执行。
不过,要注意一个例外,当exec命令来对文件描述符操作的时候,就不会替换shell,而且操作完成后,还会继续执行接下来的命令。
shell的内建命令exec将并不启动新的shell,而是用要被执行命令替换当前的shell进程,并且将老进程的环境清理掉,而且exec命令后的其它命令将不再执行。
因 此,如果你在一个shell里面,执行exec ls那么,当列出了当前目录后,这个shell就自己退出了,因为这个shell进程已被替换为仅仅执行ls命令的一个进程,执行结束自然也就退出了。为 了避免这个影响我们的使用,一般将exec命令放到一个shell脚本里面,用主脚本调用这个脚本,调用点处可以用bash a.sh,(a.sh就是存放该命令的脚本),这样会为a.sh建立一个sub shell去执行,当执行到exec后,该子脚本进程就被替换成了相应的exec的命令。
source命令或者".",不会为脚本新建shell,而只是将脚本包含的命令在当前shell执行。
解释下面的shell脚本
64 :
#!/bin/sh
rm -f fred
if [ -f fred ]; then
:
else
echo file fred does not exist
fi
exit 0
65:
#!/bin/sh
echo The date is $(date)
set $(date)
echo The month is $2
exit 0
66:
#!/bin/sh
while [ "$1" != "" ]; do
echo "$1"
shift
done
exit 0
67:
#!/bin/bash
# Write a shell script that counts English language articles (a, an, the)
# in a given text file.
#
# --------------------------------------------------------------------
# This is a free shell script under GNU GPL version 2.0 or above
# Copyright (C) 2005 nixCraft project.
# Feedback/comment/suggestions : http://cyberciti.biz/fb/
# -------------------------------------------------------------------------
# This script is part of nixCraft shell script collection (NSSC)
# Visit http://bash.cyberciti.biz/ for more information.
# -------------------------------------------------------------------------
echo -n "Enter a file name : " //参数-n的作用是不换行,echo默认是换行
read file
//从键盘输入.read命令接收标准输入(键盘)的输入,或其他文件描述符的输入
a=0
the=0
an=0
# make sure file exist
if [ ! -f $file ]
//-f filename 如果 filename为常规文件,则为真
then
echo "$file not a file!"
exit 1
//exit(1)表示异常退出
fi
# put while loop to read a $file
while read line
//读取文件$file每行直至文件尾结束
do
#process each word
for w in $line
//变量w $line取值空间
do
# convert word to lowercase; so that we can count ThE, THE, the, THe etc all
lword="$(echo $w | tr '[A-Z]' '[a-z]')" //把每个字符都转成小写
# is it 'a' article?
[[ $lword = "a" ]] && (( a++ )) || [[ $lword = "the" ]] && (( the++ )) || [[ $lword = "an" ]] && (( an++ ))
//统计a the an 的数量,分别保存在a,the和an中
done
done < $file
# display stats //输出
echo "a article occured $a times"
echo "the article occured $the times"
echo "an article occured $an times"
68:
#!/bin/bash
#同步某个文件夹,使目的文件夹的内容和源文件夹的内容保持一致,如果源文件夹的某个文件作了更新,就将其拷贝进目的文件夹,如果源文件夹的某个文件已经删除,也将目的文件夹中相应的文件删除。
sync()
{
#检查是否正确
if [ $# -ne 2 ] // $# 表示提供到shell脚本或者函数的参数总数,-ne 表示 不等于
then
echo "usage: ./sync src dst"
fi
#检查源文件夹是否存在
if [ ! -e $1 ]
//-e $1 第一个参数所指的文件夹存在 !非
then
echo "error : src don't exist"
exit 1
fi
#检查目的文件夹是否存在,如果不在,复制整个文件夹
if [ ! -e $2 ]
then
echo "cp -a $1 $2"
cp -a $1 $2 // -a 相当于-pdr ,-p保留源文件或目录的属性,-d若来源文件 //为连结文件的属性(link file),则复制连结文件属性而非档案本身, -r 递归处理,将指定目//录下的文件与子目录一并处理
return 0
fi
#删掉目的文件夹多出的文件。
for Loop in $(ls $2)
do
if [ ! -e "$1/$Loop" ] //如果不存在这个文件 $1/$Loop
then
echo "rm -fr $2/$Loop"
rm -fr "$2/$Loop"
//-f 强制 -r 递归删除目录和内容
fi
done
#循环处理当前源文件目录下的每个文件。
for Loop in $(ls $1)
do
#如果某个源文件对应的目的文件不存在,拷贝进目的文件夹。
if [ ! -e $2/$Loop ]
//如果不存在这个文件 $2/$Loop
then
echo " cp loop $1/$Loop $2/$Loop"
cp -a $1/$Loop $2/$Loop
//复制一份$1/$Loop到$2/$Loop
Continue
//进行下次循环,即继续找有没有这种文件
fi
#如果不是目录,是文件,检查是否更新,如果有,将其拷贝进目的文件。
if [ -f $1/$Loop ]
//-f filename 如果 filename为常规文件,则为真
then
#time1表示源文件的修改时间,time2表示目的文件的修改时间,如果time1大于time2,表示原文件被更新了。
//stat 显示文件的详细信息
//grep -i 不区分大小写
//cut -c :以字符为单位进行分割,9-12 表示第9个字符到第12个字符
//-gt: 大于
time1=$(stat $1/$Loop | grep -i 'modify' | cut -c 9-12,14,15,17,18,20,21,23,24,26,27)
time2=$(stat $2/$Loop | grep -i 'modify' | cut -c 9-12,14,15,17,18,20,21,23,24,26,27)
if [ $time1 -gt $time2 ]
//-gt:大于
then
echo " cp $1/$Loop $2/$Loop"
cp $1/$Loop $2/$Loop
fi
continue
fi
#如果是目录,递归调用sync函数处理。
if [ -d $1/$Loop ] //-d 如果为目录,则为真
then
sync $1/$Loop $2/$Loop // sync()函数
fi
done
}
sync $1 $2
//sync()函数
exit 0
四:make命令部分:
69 解释下面的makefile文件
a="hello world"
b=$(a)
c:=$(a)
a="good bye"
print:
@echo b= $(b)
//echo前面的@符号的作用是禁止回显 ,直接输出
//“goodbye”, 而不是输出 “ echo b=goodbye
goodbye ”
@echo c= $(c)
//c是”hello world”,因为c是:=,所以他只会从他之前找a的值
70:解释下面的makefile文件
all: myapp
//终极目标
# Which compiler
CC = gcc
//宏定义
# Where to install
INSTDIR = /usr/local/bin
//宏定义
# Where are include files kept
INCLUDE = .
//宏定义,当前目录
# Options for development
CFLAGS = -g -Wall -ansi
//-g为了调试用的
# Options for release
# CFLAGS = -O -Wall -ansi
//-o output_filename,确定输出文件的名称为output_filename,同时这个名称不能和源文件同名。如果不给出这个选项,gcc就给出预设的可执行文件a.out。
myapp: main.o 2.o 3.o
//需要的文件
$(CC) -o myapp main.o 2.o 3.o
main.o: main.c a.h
//需要的文件
$(CC) -I$(INCLUDE) $(CFLAGS) -c main.c
//-Ixxx 的意思是除了默认的头文件搜索路径(比如/usr/include等)外,同时还在路径xxx下搜索需要被引用的头文件。
//-c 表示只编译不链接,生成.o但不生成可执行文件
2.o: 2.c a.h b.h
//需要的文件
$(CC) -I$(INCLUDE) $(CFLAGS) -c 2.c
3.o: 3.c b.h c.h
//需要的文件
$(CC) -I$(INCLUDE) $(CFLAGS) -c 3.c
clean:
-rm main.o 2.o 3.o
//删除
install: myapp
@if [ -d $(INSTDIR) ]; \
//-d 是否为目录
then \
cp myapp $(INSTDIR);\
//复制mycpp到$(INSTDIR)
chmod a+x $(INSTDIR)/myapp;\
//修改$(INSTDIR)/myapp的权限;a+x表示档案拥有者、群组、其他都增加了可执行的权限。
chmod og-w $(INSTDIR)/myapp;\
//g表示与该档案的拥有者属于同一个群体(group)者,o表示其他以外的人 ,-w表示减少写//的权限。
echo "Installed in $(INSTDIR)";\
else \
echo "Sorry, $(INSTDIR) does not exist";\
fi
五:iptables部分
-t指定表
-A追加规则
-s指定ip
-j进行处理动作
-D删除规则
-p指定ip
--dport目的端口
-F删除所有规则
-L列出所有规则
-i指定接收报文的接口名称
-d指定目标地址
解释下面命令
71: iptables -t filter -A INPUT -s 202.108.22.5 -j DROP
在指定表filter 追加一条Input规则 指定ip为202.108.22.5 进行Drop处理动作
72:iptables -t filter -D INPUT -s 202.108.22.5 -j DROP
在指定表filter 删除指定指定ip为202.108.22.5 进行Drop处理动作
的INPUT规则
73:iptables -A INPUT -p tcp --dport 80 -j accept
追加Input规则 定义过滤政策tcp 指定ip协议 进行accept处理
--dport目的端口
74:iptables -F INPUT
删除INPUT上的所有规则
75:iptables -L INPUT
列出INPUT上的所有规则
76:iptable -A FORWARD -i eth1 -d 10.4.3.2 -j ACCEPT
追加一条FORWARD规则,eth1接口接收报文,目标地址为10.4.3.2,进行accept处理动作
注意: