ICode9

精准搜索请尝试: 精确搜索
首页 > 系统相关> 文章详细

Linux编程基础

2019-08-04 20:41:37  阅读:190  来源: 互联网

标签:EOF 编程 基础 cat sed Linux 字符串 filename 替换


1. EOF的用法
在平时的运维工作中,我们经常会碰到这样一个场景:
执行脚本的时候,需要往一个文件里自动输入N行内容。如果是少数的几行内容,还可以用echo追加方式,但如果是很多行,那么单纯用echo追加的方式就显得愚蠢之极了!
这个时候,就可以使用EOF结合cat命令进行行内容的追加了。
下面就对EOF的用法进行梳理:
EOF是END Of File的缩写,表示自定义终止符.既然自定义,那么EOF就不是固定的,可以随意设置别名,在linux按ctrl-d就代表EOF.
EOF一般会配合cat能够多行文本输出.
其用法如下:
<<EOF        //开始
....
EOF            //结束
还可以自定义,比如自定义:
<<BBB        //开始
....
BBB              //结束
通过cat配合重定向能够生成文件并追加操作,在它之前先熟悉几个特殊符号:
< :输入重定向
> :输出重定向
>> :输出重定向,进行追加,不会覆盖之前内容
<< :标准输入来自命令行的一对分隔号的中间内容.
先举一个简单的例子,例1:
# cat << EOF
在出现输入提示符">",输入以下内容:
> Hello
> EOF
输入结束后,在终端显示以下内容:
Hello

思考:
我们可以从cat命令的说明中知道,cat的操作对象是文件,但是例1中cat的操作对象不是文件,而是用户输入。
那么我们可以这样理解例1:先在文件file中输入“Hello”,再用cat file输出其中的内容。
也就是说我们可以用一个文件来替代"<< EOF EOF"。
反过来说,如果操作命令中的文件是输入对象,也可以用"<< EOF EOF"来替代的。

为了验证上面的思考,我们试验两个例子:
例2. 假设有如下的磁盘分区脚本:
sfdisk -uM /dev/sda << EOF
,2048,b
,1024,83
,1024,83
EOF
根据之前的思考,将"<< EOF"和"EOF"之间的内容保存到文件part中,然后将脚本修改为:
sfdisk -uM /dev/sda < part
经测试,修改后的方式可以达到同样的分区结果。

例3. 将一个文件的内容输出到另一个文件中:
# cat fileA > fileB
按照之前的思考,将"<< EOF EOF"替代输入对象文件fileA:
# cat << EOF > fileB
经测试,命令执行后提示用户输入内容,输入结束后,用户的输入内容被保存到了fileB中。

综上所述,“<< EOF EOF”的作用是在命令执行过程中用户自定义输入,它类似于起到一个临时文件的作用,只是比使用文件更方便灵活。
下面通过具体实例来感受下EOF用法的妙处:
1)向文件test.sh里输入内容。
[root@slave-server opt]# cat << EOF >test.sh 
> 123123123
> 3452354345
> asdfasdfs
>  EOF
[root@slave-server opt]# cat test.sh 
123123123
3452354345
asdfasdfs
追加内容
[root@slave-server opt]# cat << EOF >>test.sh 
> 7777
> 8888
>  EOF
[root@slave-server opt]# cat test.sh 
123123123
3452354345
asdfasdfs
7777
8888

Sed的用法 

----s后面跟的是分隔符,原字符串可使用.*这种正则表达式进行整行替换
代码如下:
sed 's/原字符串/替换字符串/'
单引号里面,s表示替换,三根斜线中间是替换的样式,特殊字符需要使用反斜线”\”进行转义,但是单引号”‘”是没有办法用反斜线”\”转义的,这时候只要把命令中的单引号改为双引号就行了,例如:
代码如下:
sed "s/原字符串包含'/替换字符串包含'/" //要处理的字符包含单引号
命令中的三根斜线分隔符可以换成别的符号,这在要替换的内容有较多斜线是较为方便,只需要紧跟s定义即可,例如换成问号”?”:
代码如下:
sed 's?原字符串?替换字符串?' //自定义分隔符为问号

可以在末尾加g替换每一个匹配的关键字,否则只替换每行的第一个,例如:
代码如下:
sed 's/原字符串/替换字符串/' //替换所有匹配关键字

上箭头”^”表示行首,美元”$”符号如果在引号中表示行尾,但是在引号外却表示末行(最后一行),这里犯二了,搜了半天哪个符号表示首行,半天才想起来,首行就是数字”1″啊.那么在行首和行尾添加字符串就是把行尾和行首替换,例如:
代码如下:
sed 's/^/添加的头部&/g' //在所有行首添加
sed 's/$/&添加的尾部/g' //在所有行末添加
sed '2s/原字符串/替换字符串/g' //替换第2行
sed '$s/原字符串/替换字符串/g' //替换最后一行
sed '2,5s/原字符串/替换字符串/g' //替换2到5行
sed '2,$s/原字符串/替换字符串/g' //替换2到最后一行

替换样式可以多个在同一条命令中执行,用分号”;”分隔,例如:
代码如下:
sed 's/^/添加的头部&/g;s/$/&添加的尾部/g' //同时执行两个替换规则
 
sed处理过的输出是直接输出到屏幕上的,要保存可以将输出重定向,或者使用参数”i”直接在文件中替换:
代码如下:
sed -i 's/原字符串/替换字符串/g' filename //替换文件中的所有匹配项
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
首先是Sed里使用变量的问题
 
网上有人总结了四种方案:
1.       eval sed 's/$a/$b/' filename
2.       sed "s/$a/$b/" filename
3.       .sed 's/'$a'/'$b'/' filename
4.       .sed s/$a/$b/ filename
我比较喜欢第二种,也就是:Sed后面的表达式一般用单引号引起来('),当需要使用变量时就换用双引号(")。
关于单双引号的区别:
单引号:shell处理命令时,对其中的内容不做任何处理。即此时是引号内的内容是sed命令所定义的格式。
双引号:shell处理命令时,要对其中的内容进行算术扩展。如果想让shell扩展后得到sed命令所要的格式,使用命令:sed -n "/\\\\$/p" haha,扩展后得到的结果即\\$.
 
因此对于语句类似:
$Comfilename="/home/evan/sandbox/Main/"
1. echo $Comfilename | sed 's#\/#\\\/#g'
2. echo $Comfilename | sed "s#\/#\\\/#g"
第一个的结果是:\/home\/evan\/sandbox\/Main\/
而第二个还是:/home/evan/sandbox/Main/ 因为双引号会将“\/“解释为”/“,所以sed "s#\/#\\\/#g"被Shell解释成了sed s#/#\/#g 到sed里执行时又把”\/“转义为”/“了,这样相当于进行了了两次解释,就得不到想要的结果了。
这个例子告诉我当没必要用双引号的的时候就不要用,要不然说不定什么时候你就会很郁闷。 当然单引号效率要比双引号高也是不要滥用双引号的原因之一。
 
言归正传,如何在sed的变量里使用那些特殊的需要转义的字符呢?
网上提出的一种方法是将sed里表示替换用的s后面的表示分隔用的字符换成别的变量里没有的字符这样就相当于变量里没有要转义的字符了。
如:
sed –i "s# $Comfilename#/Root/#" filename.list
这是一个好办法。但很不幸我需要的是删除“d”不是替换“s“。当我把同样的方法用于删除时似乎没有起到作用:sed –i "# $Comfilename#d" filename.list
 
于是只能自己手工先改写变量
$Comfilename="/home/evan/sandbox/Main/"
Tempname=` echo $Comfilename | sed 's#\/#\\\/#g'`  (这里把反单引号执行的结果给临时变量,同样的方法可以改写其他需要转义的符号。)
sed –i "# $ Tempname #d" filename.list

shell分割字符串

shell 如何用指定的分隔符来分割字符串让结果为一个字符串数组,类似 java 中的 split, 而 split 关键字已经留给文件分割了,故字符串就分割处理就不能在使用了,那如何来处理字符串串分割呢?方法有两种
方法一
1.    #!/bin/bash
2.    string="hello,shell,haha"  
3.    array=(${string//,/ })  
4.    for var in ${array[@]}
5.    do
6.       echo $var
7.    done 
?    
方法二
1.    #!/bin/bash
2.    string="hello,shell,haha"
3.    OLD_IFS="$IFS"
4.    IFS=","
5.    array=($string)
6.    IFS="$OLD_IFS"
7.    for var in ${array[@]}
8.    do
9.       echo $var
10.    done

标签:EOF,编程,基础,cat,sed,Linux,字符串,filename,替换
来源: https://blog.csdn.net/weixin_43241054/article/details/98085405

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有