码迷,mamicode.com
首页 > 系统相关 > 详细

linux 文件,字符,shell基本操作

时间:2015-08-06 13:21:04      阅读:162      评论:0      收藏:0      [点我收藏+]

标签:

最近打算开始写点shell脚本,主要涉及到日志读取处理及文件的操作,感觉挺简单,但是还有很多方法没有掌握,还得查点资料,现在把需要涉及到的知识做个记录吧。

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

举例: 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 文件是否可写

测试时逻辑操作符

-a 逻辑与,操作符两边均为真,结果为真,否则为假。
-o 逻辑或,操作符两边一边为真,结果为真,否则为假。
! 逻辑否,条件为假,结果为真。

举例: [ -w result.txt -a -w score.txt ] ;echo $? // 测试两个文件是否均可写

常见字符串测试

-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 之后

举例: name="zqf"; [ $name = "zqf" ];echo $? // 打印 0 表示变量name 的值和字符串"zqf"相等

常见数值测试


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"))

举例: x=1 ; [ $x -eq 1 ] ; echo $? // 将打印 0 表示变量x 的值等于数字1 x=a ; [ $x -eq "1" ] // shell 打印错误信息 [: a: integer expression expected

test , [] , [[]]

因为 shell 和我们通常编程语言不同,更多的情况是和它交互,总是调用别人。 所以有些本属于程序语言本身的概念在 shell 中会难以理解。"基本功" 不好, 更容易 "犯困" 了,我就是一个 :-) 。

以 bash 为例 (其他兼容 shell 差不多):

  1. test 和 [ 是 bash 的内部命令,GNU/linux 系统的 coreutils 软件包通 常也带 /usr/bin/test 和 /usr/bin/[ 命令。如果我们不用绝对路径指 明,通常我们用的都是 bash 自带的命令。
  2. [[ 是 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是否小于等于n2
n1 -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是否大于str2
str1 != str2检查str1与str2是否不同      -n str1 检查str1的长度是否大于0
str1 < str2检查str1是否小于str2         -z str1 检查str1的长度是否为0

字符串顺序:
*大于和小于符号一定要转义,否则shell会将他们当做重定向符号,将字符串值看作是文件名。
*大于和小于顺序与在sort中不同
*test使用标准的ASCII排序,使用每个字母的ASCII数值来决定排序顺序,sort命令使用为当前系统语言设置定义的排序顺序。对于英语来说,当前设置指定小写字母排在大写字母之前。

版权声明:本文为博主原创文章,未经博主允许不得转载。

linux 文件,字符,shell基本操作

标签:

原文地址:http://blog.csdn.net/richermen/article/details/47302917

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!