Linux shell字符串中指定字符替换

原来都是使用awk或者sed对文件中的匹配字符进行替换,此次是在使用shell脚本是时,对行内的某些特定字符进行替换。记录如下:

一、 shell替换

  1. echo ${string/ab/cd} #将此行的ab替换成cd,含有多个匹配的情况下,只替换一次。
  2. echo ${string//ab/cd} #将此行的ab替换成cd,双斜杠替换所有匹配。
  3. echo ${string/#abc/bb} #将以abc开头的替换成bb,和^有点像。

二、sed 命令

  • 常用的几个参数:
    a\ 在当前行下面插入文本。
    i\ 在当前行上面插入文本。
    c\ 把选定的行改为新的文本。
    d 删除,删除选择的行。
    s 替换指定字符

  • sed 替换标记
    g 表示行内全面替换。
    p 表示打印行。
    w 表示把行写入一个文件。

  • sed元字符集
    /^root/ ^ 指定行的开始
    /bash$/ $ 指定行的结束
    /ro.t/ 匹配一个非换行符的字符
    /*sh/ * 匹配零个或者多个字符
    /[Rr]oot/ []匹配一个范围内的字符
    /[^a-cA-C]sh/ [^]匹配不在指定范围的的字符
    (..) 匹配子串,保存匹配的字符,如s/(love)able/\1rs/,loveable被替换成lovers。
    s/super/YY&yy/ super变成YYsuperyy & 保存搜索字符用来替换其他字符。在字符串前后添加字符的时候此命令很好用
    / /super>/ 匹配以super单词结束的行 > 指定单词结束
    /2{3}/ 匹配包含3个2的行 /G{x} 重复字符G,x次
    /2{3,} 匹配至少包含3个2的行 /G{x} 重复字符G,至少x次
    /2{3,5} 匹配至少3个2,最多5个2的行 /G{x,y} 重复字符G,至少x次,最多y次 (没测试出来!!)

使用时

sed -n '/ sed -n '/s{2,}/p' test.txt #打印连续匹配s2次及以上的行

归纳总结如下:

元字符 功能 示例
^ 行首定位符 /^my/ 匹配所有以my开头的行
$ 行尾定位符 /my$/ 匹配所有以my结尾的行
. 匹配除换行符以外的单个字符 /m..y/ 匹配包含字母m,后跟两个任意字符,再跟字母y的行
* 匹配零个或多个前导字符 /my*/ 匹配包含字母m,后跟零个或多个y字母的行
[] 匹配指定字符组内的任一字符 /[Mm]y/ 匹配包含My或my的行
[^] 匹配不在指定字符组内的任一字符 /[^Mm]y/ 匹配包含y,但y之前的那个字符不是M或m的行
(..) 保存已匹配的字符 1,20s/youself/\1r/ 标记元字符之间的模式,并将其保存为标签1,之后可以使用\1来引用它。最多可以定义9个标签,从左边开始编号,最左边的是第一个。此例中,对第1到第20行进行处理,you被保存为标签1,如果发现youself,则替换为your。
& 保存查找串以便在替换串中引用 s/my/**&**/ 符号&代表查找串。my将被替换为**my**
< 词首定位符 /
> 词尾定位符 /my>/ 匹配包含以my结尾的单词的行
x{m} 连续m个x /9{5}/ 匹配包含连续5个9的行
x{m,} 至少m个x /9{5,}/ 匹配包含至少连续5个9的行
x{m,n} 至少m个,但不超过n个x /9{5,7}/ 匹配包含连续5到7个9的行

=======================================================================================================
sed在使用元字符过程中出现的小插曲

image.png

在一个test.txt文本中,要匹配superstar 中的super,但是在直接替换的过程中提示:sed: -e expression #1, char 25: invalid reference \1 on `s' command's RHS
错误。经查询多个资料找到了解决途径:(1)加 -r参数使用扩展的正则表达式,相当于将\1激活;或者(2)将括号加上\进行转义。参考自: https://stackoverflow.com/questions/16637799/

image.png

=======================================================================================================

常用的命令
  • p命令
    命令p用于显示模式空间的内容。默认情况下,sed把输入行打印在屏幕上,选项-n用于取消默认的打印操作。当选项-n和命令p同时出现时,sed可打印选定的内容。

sed '/my/p' datafile
#默认情况下,sed把所有输入行都打印在标准输出上。如果某行匹配模式my,p命令将把该行另外打印一遍
sed -n '/my/p' datafile
#选项-n取消sed默认的打印,p命令把匹配模式my的行打印一遍

  • d命令
    d用于删除输入行。sed先将输入行从文件复制到模式空间里,然后对该行执行sed命令,最后将模式空间里的内容显示在屏幕上。如果发出的是命令d,当前模式空间里的输入行会被删除,不被显示。

sed '$d' datafile
#删除最后一行,其余的都被显示
sed '/my/d' datafile
#删除包含my的行,其余的都被显示

  • s命令

sed 's/^My/You/g' datafile
#命令末端的g表示在行内进行全局替换,也就是说如果某行出现多个My,所有的My都被替换为You
sed -n '1,20s/My$/You/gp' datafile
#取消默认输出,处理1到20行里匹配以My结尾的行,把行内所有的My替换为You,并打印到屏幕上
sed 's#My#Your#g' datafile
#紧跟在s命令后的字符就是查找串和替换串之间的分隔符。分隔符默认为正斜杠,但可以改变。无论什么字符(换行符、反斜线除外),只要紧跟s命令,就成了新的串分隔符

  • e选项
    -e是编辑命令,用于sed执行多个编辑任务的情况下。在下一行开始编辑前,所有的编辑动作将应用到模式缓冲区中的行上。

sed -e '1,10d' -e 's/My/Your/g' datafile
#选项-e用于进行多重编辑。第一重编辑删除第1-10行。第二重编辑将出现的所有My替换为Your。因为是逐行进行这两项编辑(即这两个命令都在模式空间的当前行上执行),所以编辑命令的顺序会影响结果

  • 在特定行下一行或前一行添加一行内容
    指定的行后面或者是前面追加一行,这个时候可以使用sed来完成,具体用法如下

a\ 在指定的行后面追加一行
b\ 在指定的行前面追加一行
使用指定的行号追加内容,在使用行号的过程中,需要注意的问题有以下
N;后面只能使用偶数,且不可以为0(经测试确实只能是偶数)
a\表示在指定的行后面追加一行
i\表示在当前行插入一行,如果指定行为4,其实最终的结果插入行的位置是第三行。
sed -i 'N;2a\newline' test,txt
sed -i 'N;2i\newline' test.txt

三、 awk替换
此处以test.txt文本为例:

$more test.txt
superstar snack
p superstar superstar
p
Ok snack snack snack
superstar
sssuperstar
99999999

awk的sub/gsub函数用来替换字符串,其语法格式为

sub(/regexp/,replacement,target)
注意第三个参数是target,如果忽略则使用$0作为参数,即整行文本。
(1)替换单个串
awk '{sub(/super/,"mysuper");print $0}' test.txt
#将每行的第一个super替换成mysuper
(2)替换所有的串
awk '{gsub(/super/,"mysuper");print $0}' test.txt
#将每一行的所有super替换成mysuper。
(3)替换满足条件的行的串
awk '/snack/ {gsub(/super/,"mysuper");print $0;next}{print $0}' test.txt
# 在出现字符串snack的前提下,将行中的所有super替换为mysuper
(4)替换多个可选串
awk '{gsub(/super|sssuper/,"mysuper");print $0}' test.txt
#不管是super还是sssuper,全部替换成mysuper。
(5)全字符匹配替换
awk '{gsub(//,"mysuper");print $0}' test.txt
# 全字匹配superstar才能替换 superstar1不可替换
(6)规则表达式匹配
awk '{sub(/^super/,"mysuper");print $0}' test.txt
#匹配以super开头的行,将其替换成mysuper

你可能感兴趣的:(Linux shell字符串中指定字符替换)