linux 文件,字符,shell基本操作
2015-08-06 11:29
711 查看
最近打算开始写点shell脚本,主要涉及到日志读取处理及文件的操作,感觉挺简单,但是还有很多方法没有掌握,还得查点资料,现在把需要涉及到的知识做个记录吧。
语法格式为:
cut [-bn] [file] 或 cut [-c] [file] 或 cut [-df] [file]
cut 命令从文件的每一行剪切字节、字符和字段并将这些字节、字符和字段写至标准输出。
如果不指定 File 参数,cut 命令将读取标准输入。必须指定 -b、-c 或 -f 标志之一。
-b :以字节为单位进行分割。这些字节位置将忽略多字节字符边界,除非也指定了 -n 标志。
-c :以字符为单位进行分割。
-d :自定义分隔符,默认为制表符。
-f :与-d一起使用,指定显示哪个区域。
-n :取消分割多字节字符。仅和 -b 标志一起使用。如果字符的最后一个字节落在由 -b 标志的 List 参数指示的<br />范围之内,该字符将被写出;否则,该字符将被排除。
在这里可以用-d自定义符号来读取日志分段
sed命令行格式为:
sed [-nefri] ‘command’ 输入文本
-n∶使用安静(silent)模式。在一般 sed 的用法中,所有来自 STDIN的资料一般都会被列出到萤幕上。但如果加上 -n 参数后,则只有经过sed 特殊处理的那一行(或者动作)才会被列出来。
-e∶直接在指令列模式上进行 sed 的动作编辑;
-f∶直接将 sed 的动作写在一个档案内, -f filename 则可以执行 filename 内的sed 动作;
-r∶sed 的动作支援的是延伸型正规表示法的语法。(预设是基础正规表示法语法)
-i∶直接修改读取的档案内容,而不是由萤幕输出。
常用命令:
a ∶新增, a 的后面可以接字串,而这些字串会在新的一行出现(目前的下一行)~
c ∶取代, c 的后面可以接字串,这些字串可以取代 n1,n2 之间的行!
d ∶删除,因为是删除啊,所以 d 后面通常不接任何咚咚;
i ∶插入, i 的后面可以接字串,而这些字串会在新的一行出现(目前的上一行);
p ∶列印,亦即将某个选择的资料印出。通常 p 会与参数 sed -n 一起运作~
s ∶取代,可以直接进行取代的工作哩!通常这个 s 的动作可以搭配正规表示法!例如 1,20s/old/new/g 就是啦!
举例:(假设我们有一文件名为ab)
替换一行中的某部分
sort [-bcfMnrtk][源文件][-o 输出文件]
补充说明:sort可针对文本文件的内容,以行为单位来排序。
参 数:
-b 忽略每行前面开始出的空格字符。
-c 检查文件是否已经按照顺序排序。
-f 排序时,忽略大小写字母。
-M 将前面3个字母依照月份的缩写进行排序。
-n 依照数值的大小排序。
-o<输出文件> 将排序后的结果存入指定的文件。
-r 以相反的顺序来排序。
-t<分隔字符> 指定排序时所用的栏位分隔字符。
-k 选择以哪个区间进行排序。
:<<BLOCK'
....注释内容
'BLOCK
B、方法二
:<<'BLOCK
....注释内容
BLOCK'
C、方法三
:<<'
....注释内容
'
以上三种方法都是通过在:<
BLOCK为Here Documents中的定义符号可以随意起名,只要前后匹配就行了
更帅的方法:
2.格式
grep [options]
3.主要参数
[options]主要参数:
-c:只输出匹配行的计数。
-I:不区分大 小写(只适用于单字符)。
-h:查询多文件时不显示文件名。
-l:查询多文件时只输出包含匹配字符的文件名。
-n:显示匹配行及 行号。
-s:不显示不存在或无匹配文本的错误信息。
-v:显示不包含匹配文本的所有行。
pattern正则表达式主要参数:
\: 忽略正则表达式中特殊字符的原有含义。
^:匹配正则表达式的开始行。
$: 匹配正则表达式的结束行。
\<:从匹配正则表达 式的行开始。
\>:到匹配正则表达式的行结束。
[ ]:单个字符,如[A]即A符合要求 。
[ - ]:范围,如[A-Z],即A、B、C一直到Z都符合要求 。
。:所有的单个字符。
* :有字符,长度可以为0。
4.grep命令使用简单实例
$ grep ‘test’ d*
显示所有以d开头的文件中包含 test的行。
$ grep ‘test’ aa bb cc
显示在aa,bb,cc文件中匹配test的行。
$ grep ‘[a-z]\{5\}’ aa
显示所有包含每个字符串至少有5个连续小写字符的字符串的行。
$ grep ‘w\(es\)t.*\1′ aa
如果west被匹配,则es就被存储到内存中,并标记为1,然后搜索任意个字符(.*),这些字符后面紧跟着 另外一个es(\1),找到就显示该行。如果用egrep或grep -E,就不用”\”号进行转义,直接写成’w(es)t.*\1′就可以了。
5.grep命令使用复杂实例
假设您正在’/usr/src/Linux/Doc’目录下搜索带字符 串’magic’的文件:
$ grep magic /usr/src/Linux/Doc/*
sysrq.txt:* How do I enable the magic SysRQ key?
sysrq.txt:* How do I use the magic SysRQ key?
其中文件’sysrp.txt’包含该字符串,讨论的是 SysRQ 的功能。
默认情况下,’grep’只搜索当前目录。如果 此目录下有许多子目录,’grep’会以如下形式列出:
grep: sound: Is a directory
这可能会使’grep’ 的输出难于阅读。这里有两种解决的办法:
明确要求搜索子目录:grep -r
或忽略子目录:grep -d skip
如果有很多 输出时,您可以通过管道将其转到’less’上阅读:
$ grep magic /usr/src/Linux/Documentation/* | less
这样,您就可以更方便地阅读。
还想到一个使用搜索文件的办法
举例: if [ -b /dev/hda ] ;then echo "yes" ;else echo "no";fi // 将打印 yes
test -c /dev/hda ; echo $? // 将打印 1 表示test 命令的返回值为1,/dev/hda 不是字符设备
[ -w /etc/passwd ]; echo $? // 查看对当前用户而言,passwd 文件是否可写
举例: [ -w result.txt -a -w score.txt ] ;echo $? // 测试两个文件是否均可写
举例: name="zqf"; [ $name = "zqf" ];echo $? // 打印 0 表示变量name 的值和字符串"zqf"相等
在 (()) 中的测试:
举例: x=1 ; [ $x -eq 1 ] ; echo $? // 将打印 0 表示变量x 的值等于数字1 x=a ; [ $x -eq "1" ] // shell 打印错误信息 [: a: integer expression expected
以 bash 为例 (其他兼容 shell 差不多):
test 和 [ 是 bash 的内部命令,GNU/linux 系统的 coreutils 软件包通 常也带 /usr/bin/test 和 /usr/bin/[ 命令。如果我们不用绝对路径指 明,通常我们用的都是 bash 自带的命令。
[[ 是 bash 程序语言的关键字!
绝大多数情况下,这个三个功能通用。但是命令和关键字总是有区别的。命令和 关键字的差别有多大呢?
如果是命令,它就和参数组合为一体被 shell 解释,那样比如 ">" "<" 就被 shell 解释为重定向符号了。关键字却不这样。
[ 中使用 -a 和 -o 表示逻辑与和逻辑或。
expr $args + 0 &>/dev/null
方法2:打印变量通过sed替换的方式,将变量中的数字替换为空,如果执行替换后变量为空,则为整数
echo $args | sed 's/[0-9]//g'
如果判断负数则再用sed过滤负号
echo $args | sed 's/[0-9]//g' | sed 's/-//g'
下面的脚本通过两个函数来实现数值判断。代码很简单,就不加注释了。
n1 -ge n2检查n1是否大于等于n2 n1 -lt n2检查n1是否小于n2
n1 -gt n2检查n1是否大于n2 n1 -ne n2检查n1是否不等于n2
推出状态码退出。
str1 != str2检查str1与str2是否不同 -n str1 检查str1的长度是否大于0
str1 < str2检查str1是否小于str2 -z str1 检查str1的长度是否为0
字符串顺序:
*大于和小于符号一定要转义,否则shell会将他们当做重定向符号,将字符串值看作是文件名。
*大于和小于顺序与在sort中不同
*test使用标准的ASCII排序,使用每个字母的ASCII数值来决定排序顺序,sort命令使用为当前系统语言设置定义的排序顺序。对于英语来说,当前设置指定小写字母排在大写字母之前。
cp(选项)(参数)
-a:此参数的效果和同时指定"-dpR"参数相同;
-d:当复制符号连接时,把目标文件或目录也建立为符号连接,并指向与源文件或目录连接的原始文件或目录;
-f:强行复制文件或目录,不论目标文件或目录是否已存在;
-i:覆盖既有文件之前先询问用户;
-l:对源文件建立硬连接,而非复制文件;
-p:保留源文件或目录的属性;
-R/r:递归处理,将指定目录下的所有文件与子目录一并处理;
-s:对源文件建立符号连接,而非复制文件;
-u:使用这项参数后只会在源文件的更改时间较目标文件更新时或是名称相互对应的目标文件并不存在时,才复制文件;
-S:在备份文件时,用指定的后缀“SUFFIX”代替文件的默认后缀;
-b:覆盖已存在的文件目标前将目标文件备份;
-v:详细显示命令执行的操作。
源文件:制定源文件列表。默认情况下,cp命令不能复制目录,如果要复制目录,则必须使用-R选项;
目标文件:指定目标文件。当“源文件”为多个文件时,要求“目标文件”为指定的目录。
注意事项:
如果把一个文件复制到一个目标文件中,而目标文件已经存在,那么,该目标文件的内容将被破坏。
此命令中所有参数既可以是绝对路径名,也可以是相对路径名。
通常会用到点.或点点..的形式。例如,下面的命令将指定文件复制到当前目录下:
所有目标文件指定的目录必须是己经存在的,cp命令不能创建目录。如果没有文件复制的权限,则系统会显示出错信息。
将文件file复制到目录/usr/men/tmp下,并改名为file1
将目录/usr/men下的所有文件及其子目录复制到目录/usr/zh中
交互式地将目录/usr/men中的以m打头的所有.c文件复制到目录/usr/zh中
我们在Linux下使用cp命令复制文件时候,有时候会需要覆盖一些同名文件,覆盖文件的时候都会有提示:需要不停的按Y来确定执行覆盖。文件数量不多还好,但是要是几百个估计按Y都要吐血了,于是折腾来半天总结了一个方法:
1.命令格式:
du [选项][文件]
2.命令功能:
显示每个文件和目录的磁盘使用空间。
3.命令参数:
-a或-all 显示目录中个别文件的大小。
-b或-bytes 显示目录或文件大小时,以byte为单位。
-c或--total 除了显示个别目录或文件的大小外,同时也显示所有目录或文件的总和。
-k或--kilobytes 以KB(1024bytes)为单位输出。
-m或--megabytes 以MB为单位输出。
-s或--summarize 仅显示总计,只列出最后加总的值。
-h或--human-readable 以K,M,G为单位,提高信息的可读性。
-x或--one-file-xystem 以一开始处理时的文件系统为准,若遇上其它不同的文件系统目录则略过。
-L<符号链接>或--dereference<符号链接> 显示选项中所指定符号链接的源文件大小。
-S或--separate-dirs 显示个别目录的大小时,并不含其子目录的大小。
-X<文件>或--exclude-from=<文件> 在<文件>指定目录或文件。
--exclude=<目录或文件> 略过指定的目录或文件。
-D或--dereference-args 显示指定符号链接的源文件大小。
-H或--si 与-h参数相同,但是K,M,G是以1000为换算单位。
-l或--count-links 重复计算硬件链接的文件。
参数:
-c :建立一个压缩文件的参数指令(create 的意思);
-x :解开一个压缩文件的参数指令!
-t :查看 tarfile 里面的文件!
特别注意,在参数的下达中, c/x/t 仅能存在一个!不可同时存在!
因为不可能同时压缩与解压缩。
-z :是否同时具有 gzip 的属性?亦即是否需要用 gzip 压缩?
-j :是否同时具有 bzip2 的属性?亦即是否需要用 bzip2 压缩?
-v :压缩的过程中显示文件!这个常用,但不建议用在背景执行过程!
-f :使用档名,请留意,在 f 之后要立即接档名喔!不要再加参数!
例如使用『 tar -zcvfP tfile sfile』就是错误的写法,要写成
『 tar -zcvPf tfile sfile』才对喔!
-p :使用原文件的原来属性(属性不会依据使用者而变)
-P :可以使用绝对路径来压缩!
-N :比后面接的日期(yyyy/mm/dd)还要新的才会被打包进新建的文件中!
--exclude FILE:在压缩的过程中,不要将 FILE 打包!
范例:
范例一:将整个 /etc 目录下的文件全部打包成为 /tmp/etc.tar
[root@linux ~]# tar -cvf /tmp/etc.tar /etc <==仅打包,不压缩!
[root@linux ~]# tar -zcvf /tmp/etc.tar.gz /etc <==打包后,以 gzip 压缩
[root@linux ~]# tar -jcvf /tmp/etc.tar.bz2 /etc <==打包后,以 bzip2 压缩
# 特别注意,在参数 f 之后的文件档名是自己取的,我们习惯上都用 .tar 来作为辨识。
# 如果加 z 参数,则以 .tar.gz 或 .tgz 来代表 gzip 压缩过的 tar file ~
# 如果加 j 参数,则以 .tar.bz2 来作为附档名啊~
# 上述指令在执行的时候,会显示一个警告讯息:
# 『tar: Removing leading `/' from member names』那是关於绝对路径的特殊设定。
范例二:查阅上述 /tmp/etc.tar.gz 文件内有哪些文件?
[root@linux ~]# tar -ztvf /tmp/etc.tar.gz
# 由於我们使用 gzip 压缩,所以要查阅该 tar file 内的文件时,
# 就得要加上 z 这个参数了!这很重要的!
范例三:将 /tmp/etc.tar.gz 文件解压缩在 /usr/local/src 底下
[root@linux ~]# cd /usr/local/src
[root@linux src]# tar -zxvf /tmp/etc.tar.gz
# 在预设的情况下,我们可以将压缩档在任何地方解开的!以这个范例来说,
# 我先将工作目录变换到 /usr/local/src 底下,并且解开 /tmp/etc.tar.gz ,
# 则解开的目录会在 /usr/local/src/etc 呢!另外,如果您进入 /usr/local/src/etc
# 则会发现,该目录下的文件属性与 /etc/ 可能会有所不同喔!
范例四:在 /tmp 底下,我只想要将 /tmp/etc.tar.gz 内的 etc/passwd 解开而已
[root@linux ~]# cd /tmp
[root@linux tmp]# tar -zxvf /tmp/etc.tar.gz etc/passwd
# 我可以透过 tar -ztvf 来查阅 tarfile 内的文件名称,如果单只要一个文件,
# 就可以透过这个方式来下达!注意到! etc.tar.gz 内的根目录 / 是被拿掉了!
范例五:将 /etc/ 内的所有文件备份下来,并且保存其权限!
[root@linux ~]# tar -zxvpf /tmp/etc.tar.gz /etc
# 这个 -p 的属性是很重要的,尤其是当您要保留原本文件的属性时!
范例六:在 /home 当中,比 2005/06/01 新的文件才备份
[root@linux ~]# tar -N '2005/06/01' -zcvf home.tar.gz /home
范例七:我要备份 /home, /etc ,但不要 /home/dmtsai
[root@linux ~]# tar --exclude /home/dmtsai -zcvf myfile.tar.gz /home/* /etc
范例八:将 /etc/ 打包后直接解开在 /tmp 底下,而不产生文件!
[root@linux ~]# cd /tmp
[root@linux tmp]# tar -cvf - /etc | tar -xvf -
cut:
cut是一个选取命令,就是将一段数据经过分析,取出我们想要的。一般来说,选取信息通常是针对“行”来进行分析的,并不是整篇信息分析的.语法格式为:
cut [-bn] [file] 或 cut [-c] [file] 或 cut [-df] [file]
cut 命令从文件的每一行剪切字节、字符和字段并将这些字节、字符和字段写至标准输出。
如果不指定 File 参数,cut 命令将读取标准输入。必须指定 -b、-c 或 -f 标志之一。
-b :以字节为单位进行分割。这些字节位置将忽略多字节字符边界,除非也指定了 -n 标志。
-c :以字符为单位进行分割。
-d :自定义分隔符,默认为制表符。
-f :与-d一起使用,指定显示哪个区域。
-n :取消分割多字节字符。仅和 -b 标志一起使用。如果字符的最后一个字节落在由 -b 标志的 List 参数指示的<br />范围之内,该字符将被写出;否则,该字符将被排除。
在这里可以用-d自定义符号来读取日志分段
sed
sed是一个很好的文件处理工具,本身是一个管道命令,主要是以行为单位进行处理,可以将数据行进行替换、删除、新增、选取等特定工作,下面先了解一下sed的用法sed命令行格式为:
sed [-nefri] ‘command’ 输入文本
-n∶使用安静(silent)模式。在一般 sed 的用法中,所有来自 STDIN的资料一般都会被列出到萤幕上。但如果加上 -n 参数后,则只有经过sed 特殊处理的那一行(或者动作)才会被列出来。
-e∶直接在指令列模式上进行 sed 的动作编辑;
-f∶直接将 sed 的动作写在一个档案内, -f filename 则可以执行 filename 内的sed 动作;
-r∶sed 的动作支援的是延伸型正规表示法的语法。(预设是基础正规表示法语法)
-i∶直接修改读取的档案内容,而不是由萤幕输出。
常用命令:
a ∶新增, a 的后面可以接字串,而这些字串会在新的一行出现(目前的下一行)~
c ∶取代, c 的后面可以接字串,这些字串可以取代 n1,n2 之间的行!
d ∶删除,因为是删除啊,所以 d 后面通常不接任何咚咚;
i ∶插入, i 的后面可以接字串,而这些字串会在新的一行出现(目前的上一行);
p ∶列印,亦即将某个选择的资料印出。通常 p 会与参数 sed -n 一起运作~
s ∶取代,可以直接进行取代的工作哩!通常这个 s 的动作可以搭配正规表示法!例如 1,20s/old/new/g 就是啦!
举例:(假设我们有一文件名为ab)
删除某行 [root@localhost ruby] # sed '1d' ab #删除第一行 [root@localhost ruby] # sed '$d' ab #删除最后一行 [root@localhost ruby] # sed '1,2d' ab #删除第一行到第二行 [root@localhost ruby] # sed '2,$d' ab #删除第二行到最后一行 显示某行 . [root@localhost ruby] # sed -n '1p' ab #显示第一行 [root@localhost ruby] # sed -n '$p' ab #显示最后一行 [root@localhost ruby] # sed -n '1,2p' ab #显示第一行到第二行 [root@localhost ruby] # sed -n '2,$p' ab #显示第二行到最后一行 使用模式进行查询 [root@localhost ruby] # sed -n '/ruby/p' ab #查询包括关键字ruby所在所有行 [root@localhost ruby] # sed -n '/\$/p' ab #查询包括关键字$所在所有行,使用反斜线\屏蔽特殊含义 增加一行或多行字符串 [root@localhost ruby]# cat ab Hello! ruby is me,welcome to my blog. end [root@localhost ruby] # sed '1a drink tea' ab #第一行后增加字符串"drink tea" Hello! drink tea ruby is me,welcome to my blog. end [root@localhost ruby] # sed '1,3a drink tea' ab #第一行到第三行后增加字符串"drink tea" Hello! drink tea ruby is me,welcome to my blog. drink tea end drink tea [root@localhost ruby] # sed '1a drink tea\nor coffee' ab #第一行后增加多行,使用换行符\n Hello! drink tea or coffee ruby is me,welcome to my blog. end 代替一行或多行 [root@localhost ruby] # sed '1c Hi' ab #第一行代替为Hi Hi ruby is me,welcome to my blog. end [root@localhost ruby] # sed '1,2c Hi' ab #第一行到第二行代替为Hi Hi end
替换一行中的某部分
sort
sort命令是帮我们依据不同的数据类型进行排序,其语法及常用参数格式:sort [-bcfMnrtk][源文件][-o 输出文件]
补充说明:sort可针对文本文件的内容,以行为单位来排序。
参 数:
-b 忽略每行前面开始出的空格字符。
-c 检查文件是否已经按照顺序排序。
-f 排序时,忽略大小写字母。
-M 将前面3个字母依照月份的缩写进行排序。
-n 依照数值的大小排序。
-o<输出文件> 将排序后的结果存入指定的文件。
-r 以相反的顺序来排序。
-t<分隔字符> 指定排序时所用的栏位分隔字符。
-k 选择以哪个区间进行排序。
shell注释-->
A、方法一:<<BLOCK'
....注释内容
'BLOCK
B、方法二
:<<'BLOCK
....注释内容
BLOCK'
C、方法三
:<<'
....注释内容
'
以上三种方法都是通过在:<
BLOCK为Here Documents中的定义符号可以随意起名,只要前后匹配就行了
更帅的方法:
cat <<"EOF" > /dev/null this is a multi- line comment EOF或者:
: cat <<"EOF" this is a multi- line comment EOF<--shell注释
Grep
grep命令是一种强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹 配的行打印出来。grep全称是Global Regular Expression Print,表示全局正则表达式版本,它的使用权限是所有用户。2.格式
grep [options]
3.主要参数
[options]主要参数:
-c:只输出匹配行的计数。
-I:不区分大 小写(只适用于单字符)。
-h:查询多文件时不显示文件名。
-l:查询多文件时只输出包含匹配字符的文件名。
-n:显示匹配行及 行号。
-s:不显示不存在或无匹配文本的错误信息。
-v:显示不包含匹配文本的所有行。
pattern正则表达式主要参数:
\: 忽略正则表达式中特殊字符的原有含义。
^:匹配正则表达式的开始行。
$: 匹配正则表达式的结束行。
\<:从匹配正则表达 式的行开始。
\>:到匹配正则表达式的行结束。
[ ]:单个字符,如[A]即A符合要求 。
[ - ]:范围,如[A-Z],即A、B、C一直到Z都符合要求 。
。:所有的单个字符。
* :有字符,长度可以为0。
4.grep命令使用简单实例
$ grep ‘test’ d*
显示所有以d开头的文件中包含 test的行。
$ grep ‘test’ aa bb cc
显示在aa,bb,cc文件中匹配test的行。
$ grep ‘[a-z]\{5\}’ aa
显示所有包含每个字符串至少有5个连续小写字符的字符串的行。
$ grep ‘w\(es\)t.*\1′ aa
如果west被匹配,则es就被存储到内存中,并标记为1,然后搜索任意个字符(.*),这些字符后面紧跟着 另外一个es(\1),找到就显示该行。如果用egrep或grep -E,就不用”\”号进行转义,直接写成’w(es)t.*\1′就可以了。
5.grep命令使用复杂实例
假设您正在’/usr/src/Linux/Doc’目录下搜索带字符 串’magic’的文件:
$ grep magic /usr/src/Linux/Doc/*
sysrq.txt:* How do I enable the magic SysRQ key?
sysrq.txt:* How do I use the magic SysRQ key?
其中文件’sysrp.txt’包含该字符串,讨论的是 SysRQ 的功能。
默认情况下,’grep’只搜索当前目录。如果 此目录下有许多子目录,’grep’会以如下形式列出:
grep: sound: Is a directory
这可能会使’grep’ 的输出难于阅读。这里有两种解决的办法:
明确要求搜索子目录:grep -r
或忽略子目录:grep -d skip
如果有很多 输出时,您可以通过管道将其转到’less’上阅读:
$ grep magic /usr/src/Linux/Documentation/* | less
这样,您就可以更方便地阅读。
还想到一个使用搜索文件的办法
aa=$(find file) cp $aa /home rm $aa
test
-b filename | 当filename 存在并且是块文件时返回真(返回0) |
-c filename | 当filename 存在并且是字符文件时返回真 |
-d pathname | 当pathname 存在并且是一个目录时返回真 |
-e pathname | 当由pathname 指定的文件或目录存在时返回真 |
-f filename | 当filename 存在并且是正规文件时返回真 |
-g pathname | 当由pathname 指定的文件或目录存在并且设置了SGID 位时返回真 |
-h filename | 当filename 存在并且是符号链接文件时返回真 (或 -L filename) |
-k pathname | 当由pathname 指定的文件或目录存在并且设置了"粘滞"位时返回真 |
-p filename | 当filename 存在并且是命名管道时返回真 |
-r pathname | 当由pathname 指定的文件或目录存在并且可读时返回真 |
-s filename | 当filename 存在并且文件大小大于0 时返回真 |
-S filename | 当filename 存在并且是socket 时返回真 |
-t fd | 当fd 是与终端设备相关联的文件描述符时返回真 |
-u pathname | 当由pathname 指定的文件或目录存在并且设置了SUID 位时返回真 |
-w pathname | 当由pathname 指定的文件或目录存在并且可写时返回真 |
-x pathname | 当由pathname 指定的文件或目录存在并且可执行时返回真 |
-O pathname | 当由pathname 存在并且被当前进程的有效用户id 的用户拥有时返回真(字母O 大写) |
-G pathname | 当由pathname 存在并且属于当前进程的有效用户id 的用户的用户组时返回真 |
file1 -nt file2 | file1 比file2 新时返回真 |
file1 -ot file2 | file1 比file2 旧时返回真 |
f1 -ef f2 | files f1 and f2 are hard links to the same file |
test -c /dev/hda ; echo $? // 将打印 1 表示test 命令的返回值为1,/dev/hda 不是字符设备
[ -w /etc/passwd ]; echo $? // 查看对当前用户而言,passwd 文件是否可写
测试时逻辑操作符
-a | 逻辑与,操作符两边均为真,结果为真,否则为假。 |
-o | 逻辑或,操作符两边一边为真,结果为真,否则为假。 |
! | 逻辑否,条件为假,结果为真。 |
常见字符串测试
-z string | 字符串string 为空串(长度为0)时返回真 |
-n string | 字符串string 为非空串时返回真 |
str1 = str2 | 字符串str1 和字符串str2 相等时返回真 |
str1 == str2 | 同 = |
str1 != str2 | 字符串str1 和字符串str2 不相等时返回真 |
str1 < str2 | 按字典顺序排序,字符串str1 在字符串str2 之前 |
str1 > str2 | 按字典顺序排序,字符串str1 在字符串str2 之后 |
常见数值测试
int1 -eq int2 | 如果int1 等于int2,则返回真 |
int1 -ne int2 | 如果int1 不等于int2,则返回真 |
int1 -lt int2 | 如果int1 小于int2,则返回真 |
int1 -le int2 | 如果int1 小于等于int2,则返回真 |
int1 -gt int2 | 如果int1 大于int2,则返回真 |
int1 -ge int2 | 如果int1 大于等于int2,则返回真 |
< | 小于(在双括号里使用) | (("$a" < "$b")) |
<= | 小于等于 (在双括号里使用) | (("$a" <= "$b")) |
> | 大于 (在双括号里使用) | (("$a" > "$b")) |
>= | 大于等于(在双括号里使用) | (("$a" >= "$b")) |
test , [] , [[]]
因为 shell 和我们通常编程语言不同,更多的情况是和它交互,总是调用别人。 所以有些本属于程序语言本身的概念在 shell 中会难以理解。"基本功" 不好, 更容易 "犯困" 了,我就是一个 :-) 。以 bash 为例 (其他兼容 shell 差不多):
test 和 [ 是 bash 的内部命令,GNU/linux 系统的 coreutils 软件包通 常也带 /usr/bin/test 和 /usr/bin/[ 命令。如果我们不用绝对路径指 明,通常我们用的都是 bash 自带的命令。
[[ 是 bash 程序语言的关键字!
$ ls -l /usr/bin/[ /usr/bin/test -rwxr-xr-x 1 root root 37400 9月 18 15:25 /usr/bin/[ -rwxr-xr-x 1 root root 33920 9月 18 15:25 /usr/bin/test $ type [ [[ test [ is a shell builtin [[ is a shell keyword test is a shell builtin
绝大多数情况下,这个三个功能通用。但是命令和关键字总是有区别的。命令和 关键字的差别有多大呢?
如果是命令,它就和参数组合为一体被 shell 解释,那样比如 ">" "<" 就被 shell 解释为重定向符号了。关键字却不这样。
[[ 中使用 && 和 ||在
[ 中使用 -a 和 -o 表示逻辑与和逻辑或。
[[ 中可以使用通配符
arch=i486 [[ $arch = i*86 ]] && echo "arch is x86!"
[[ 中匹配字符串或通配符,不需要引号
[[ $arch_com = i386 || $ARCH = i*86 ]] && cat >> $TFS_REPO <<EOF [tfs-i386] name=GTES11.3 prelim1 baseurl=${BASEURL}i386/ enabled=1 EO
shell 判断变量为数字
方法1:通过expr 计算变量与一个整数值相加,如果能正常执行则为整数,否则执行出错,$?将是非0的值expr $args + 0 &>/dev/null
方法2:打印变量通过sed替换的方式,将变量中的数字替换为空,如果执行替换后变量为空,则为整数
echo $args | sed 's/[0-9]//g'
如果判断负数则再用sed过滤负号
echo $args | sed 's/[0-9]//g' | sed 's/-//g'
下面的脚本通过两个函数来实现数值判断。代码很简单,就不加注释了。
#!/bin/bash usage(){ cat <<EOF USEAGE:sh $0 args1 args2 exit 1 EOF } checkInt(){ expr $1 + 0 &>/dev/null [ $? -ne 0 ] && { echo "Args must be integer!";exit 1; } } checkInt1(){ tmp=`echo $1 |sed 's/[0-9]//g'` [ -n "${tmp}" ]&& { echo "Args must be integer!";exit 1; } } [ $# -ne 2 ]&&usage args1=$1 args2=$2 checkInt $args1 checkInt1 $args2 if [ $args1 -gt $args2 ];then echo "yes,$args1 greate than $args2" else echo "no,$args1 less than $args2" fi
数值比较:
n1 -eq n2检查n1是否等于n2 n1 -le n2检查n1是否小于等于n2n1 -ge n2检查n1是否大于等于n2 n1 -lt n2检查n1是否小于n2
n1 -gt n2检查n1是否大于n2 n1 -ne n2检查n1是否不等于n2
推出状态码退出。
if test condition then commands fi
字符串比较:
str1 == str2检查str1与str2是否相同 str1 > str2检查str1是否大于str2str1 != str2检查str1与str2是否不同 -n str1 检查str1的长度是否大于0
str1 < str2检查str1是否小于str2 -z str1 检查str1的长度是否为0
字符串顺序:
*大于和小于符号一定要转义,否则shell会将他们当做重定向符号,将字符串值看作是文件名。
*大于和小于顺序与在sort中不同
*test使用标准的ASCII排序,使用每个字母的ASCII数值来决定排序顺序,sort命令使用为当前系统语言设置定义的排序顺序。对于英语来说,当前设置指定小写字母排在大写字母之前。
cp
也就是copy命令cp(选项)(参数)
-a:此参数的效果和同时指定"-dpR"参数相同;
-d:当复制符号连接时,把目标文件或目录也建立为符号连接,并指向与源文件或目录连接的原始文件或目录;
-f:强行复制文件或目录,不论目标文件或目录是否已存在;
-i:覆盖既有文件之前先询问用户;
-l:对源文件建立硬连接,而非复制文件;
-p:保留源文件或目录的属性;
-R/r:递归处理,将指定目录下的所有文件与子目录一并处理;
-s:对源文件建立符号连接,而非复制文件;
-u:使用这项参数后只会在源文件的更改时间较目标文件更新时或是名称相互对应的目标文件并不存在时,才复制文件;
-S:在备份文件时,用指定的后缀“SUFFIX”代替文件的默认后缀;
-b:覆盖已存在的文件目标前将目标文件备份;
-v:详细显示命令执行的操作。
源文件:制定源文件列表。默认情况下,cp命令不能复制目录,如果要复制目录,则必须使用-R选项;
目标文件:指定目标文件。当“源文件”为多个文件时,要求“目标文件”为指定的目录。
注意事项:
如果把一个文件复制到一个目标文件中,而目标文件已经存在,那么,该目标文件的内容将被破坏。
此命令中所有参数既可以是绝对路径名,也可以是相对路径名。
通常会用到点.或点点..的形式。例如,下面的命令将指定文件复制到当前目录下:
cp ../mary/homework/assign .
所有目标文件指定的目录必须是己经存在的,cp命令不能创建目录。如果没有文件复制的权限,则系统会显示出错信息。
将文件file复制到目录/usr/men/tmp下,并改名为file1
cp file /usr/men/tmp/file1
将目录/usr/men下的所有文件及其子目录复制到目录/usr/zh中
cp -r /usr/men /usr/zh
交互式地将目录/usr/men中的以m打头的所有.c文件复制到目录/usr/zh中
cp -i /usr/men m*.c /usr/zh
我们在Linux下使用cp命令复制文件时候,有时候会需要覆盖一些同名文件,覆盖文件的时候都会有提示:需要不停的按Y来确定执行覆盖。文件数量不多还好,但是要是几百个估计按Y都要吐血了,于是折腾来半天总结了一个方法:
cp aaa/* /bbb 复制目录aaa下所有到/bbb目录下,这时如果/bbb目录下有和aaa同名的文件,需要按Y来确认并且会略过aaa目录下的子目录。 cp -r aaa/* /bbb 这次依然需要按Y来确认操作,但是没有忽略子目录。 cp -r -a aaa/* /bbb 依然需要按Y来确认操作,并且把aaa目录以及子目录和文件属性也传递到了/bbb。 \cp -r -a aaa/* /bbb 成功,没有提示按Y、传递了目录属性、没有略过目录。
du
du命令是查看使用空间的1.命令格式:
du [选项][文件]
2.命令功能:
显示每个文件和目录的磁盘使用空间。
3.命令参数:
-a或-all 显示目录中个别文件的大小。
-b或-bytes 显示目录或文件大小时,以byte为单位。
-c或--total 除了显示个别目录或文件的大小外,同时也显示所有目录或文件的总和。
-k或--kilobytes 以KB(1024bytes)为单位输出。
-m或--megabytes 以MB为单位输出。
-s或--summarize 仅显示总计,只列出最后加总的值。
-h或--human-readable 以K,M,G为单位,提高信息的可读性。
-x或--one-file-xystem 以一开始处理时的文件系统为准,若遇上其它不同的文件系统目录则略过。
-L<符号链接>或--dereference<符号链接> 显示选项中所指定符号链接的源文件大小。
-S或--separate-dirs 显示个别目录的大小时,并不含其子目录的大小。
-X<文件>或--exclude-from=<文件> 在<文件>指定目录或文件。
--exclude=<目录或文件> 略过指定的目录或文件。
-D或--dereference-args 显示指定符号链接的源文件大小。
-H或--si 与-h参数相同,但是K,M,G是以1000为换算单位。
-l或--count-links 重复计算硬件链接的文件。
tar
tar [-cxtzjvfpPN] 文件与目录 ....参数:
-c :建立一个压缩文件的参数指令(create 的意思);
-x :解开一个压缩文件的参数指令!
-t :查看 tarfile 里面的文件!
特别注意,在参数的下达中, c/x/t 仅能存在一个!不可同时存在!
因为不可能同时压缩与解压缩。
-z :是否同时具有 gzip 的属性?亦即是否需要用 gzip 压缩?
-j :是否同时具有 bzip2 的属性?亦即是否需要用 bzip2 压缩?
-v :压缩的过程中显示文件!这个常用,但不建议用在背景执行过程!
-f :使用档名,请留意,在 f 之后要立即接档名喔!不要再加参数!
例如使用『 tar -zcvfP tfile sfile』就是错误的写法,要写成
『 tar -zcvPf tfile sfile』才对喔!
-p :使用原文件的原来属性(属性不会依据使用者而变)
-P :可以使用绝对路径来压缩!
-N :比后面接的日期(yyyy/mm/dd)还要新的才会被打包进新建的文件中!
--exclude FILE:在压缩的过程中,不要将 FILE 打包!
范例:
范例一:将整个 /etc 目录下的文件全部打包成为 /tmp/etc.tar
[root@linux ~]# tar -cvf /tmp/etc.tar /etc <==仅打包,不压缩!
[root@linux ~]# tar -zcvf /tmp/etc.tar.gz /etc <==打包后,以 gzip 压缩
[root@linux ~]# tar -jcvf /tmp/etc.tar.bz2 /etc <==打包后,以 bzip2 压缩
# 特别注意,在参数 f 之后的文件档名是自己取的,我们习惯上都用 .tar 来作为辨识。
# 如果加 z 参数,则以 .tar.gz 或 .tgz 来代表 gzip 压缩过的 tar file ~
# 如果加 j 参数,则以 .tar.bz2 来作为附档名啊~
# 上述指令在执行的时候,会显示一个警告讯息:
# 『tar: Removing leading `/' from member names』那是关於绝对路径的特殊设定。
范例二:查阅上述 /tmp/etc.tar.gz 文件内有哪些文件?
[root@linux ~]# tar -ztvf /tmp/etc.tar.gz
# 由於我们使用 gzip 压缩,所以要查阅该 tar file 内的文件时,
# 就得要加上 z 这个参数了!这很重要的!
范例三:将 /tmp/etc.tar.gz 文件解压缩在 /usr/local/src 底下
[root@linux ~]# cd /usr/local/src
[root@linux src]# tar -zxvf /tmp/etc.tar.gz
# 在预设的情况下,我们可以将压缩档在任何地方解开的!以这个范例来说,
# 我先将工作目录变换到 /usr/local/src 底下,并且解开 /tmp/etc.tar.gz ,
# 则解开的目录会在 /usr/local/src/etc 呢!另外,如果您进入 /usr/local/src/etc
# 则会发现,该目录下的文件属性与 /etc/ 可能会有所不同喔!
范例四:在 /tmp 底下,我只想要将 /tmp/etc.tar.gz 内的 etc/passwd 解开而已
[root@linux ~]# cd /tmp
[root@linux tmp]# tar -zxvf /tmp/etc.tar.gz etc/passwd
# 我可以透过 tar -ztvf 来查阅 tarfile 内的文件名称,如果单只要一个文件,
# 就可以透过这个方式来下达!注意到! etc.tar.gz 内的根目录 / 是被拿掉了!
范例五:将 /etc/ 内的所有文件备份下来,并且保存其权限!
[root@linux ~]# tar -zxvpf /tmp/etc.tar.gz /etc
# 这个 -p 的属性是很重要的,尤其是当您要保留原本文件的属性时!
范例六:在 /home 当中,比 2005/06/01 新的文件才备份
[root@linux ~]# tar -N '2005/06/01' -zcvf home.tar.gz /home
范例七:我要备份 /home, /etc ,但不要 /home/dmtsai
[root@linux ~]# tar --exclude /home/dmtsai -zcvf myfile.tar.gz /home/* /etc
范例八:将 /etc/ 打包后直接解开在 /tmp 底下,而不产生文件!
[root@linux ~]# cd /tmp
[root@linux tmp]# tar -cvf - /etc | tar -xvf -
相关文章推荐
- shell脚本中切换用户执行相应的命令或者shell脚本的方法
- shell 知识点备忘
- Linux 系统下Fortran调用shell
- shell学习
- shell学习笔记
- shell字符串截取操作
- shell 中数学计算总结
- shell脚本算术运算
- linux使用普通账户时,无法登录,提示“-bash: fork: retry: Resource temporarily unavailable”
- shell计算日期之间的天数
- shell脚本学习笔记之正则表达式
- shell脚本统计出日志文件操作以及其对应的平均时间
- Shell - 打包,压缩及解压缩指令汇总
- shell 判断变量中是否包含某个字符串
- 关于linux shell编程,alias rm='cp $@ ~/backup; rm $@'
- qibocms /hr/listperson.php File Arbitrarily Include Vul Via Variable Uninitialization && Front Page Upload WEBSHELL
- linux下shell显示-bash-4.1#不显示路径解决方法
- linux定时执行shell脚本
- Linux Shell 中的反引号(`),单引号('),双引号 (")
- hive 中使用shell/python