shell脚本 文件内容查找和替换 学习实践

不是系统的学习,只是学习一下常用的命令,理解可能有错误,如果有路过的大神能够补充和指正,万分感谢!

1.根据文件名查找文件

1.1利用find命令

find [path] -type f -name '[filename]' ! -path "[excludepath]"

path目录及子目录中寻找名字为filename的文件,并打印。[path]为空的时候查找当前目录及当前目录子目录下所有名字为filename的文件,忽略excludepath目录及其子目录下的结果。例如:

//查找当前目录及子目录下的所有.sh文件并打印
$ find . -name '*.sh' 
//查找catkin_ws目录及子目录下所有名为‘main.cpp’的文件并打印
$ find ~/catkin_ws -name 'main.cpp' 

查找catkin_ws目录及子目录下所有名为‘main.cpp’的文件并打印

1.2利用grep命令

有空总结

2.文件内容查找和替换

https://blog.csdn.net/xiexingshishu/article/details/50514132

2.1 文件内容查找

2.1.1利用sed命令

sed -n '/[text]/p' [filename]

filename文件中查找text并将所在行打印出来。
例如:

//在当前目录下asdf.aaa文件中查找'ff'字符串并打印所在行
$ sed -n '/ff/p' ./asdf.aaa
asdfasdff
ff1

2.1.2利用grep命令

grep查找文件内容指南有空再总结

grep [text] [filename]

filename中查找text并打印,例如

//在aaa.aaa文件中查找aaa并打印所在行
grep aaa aaa.aaa
//在aaa.aaa文件中查找aaa(忽略大小写)并打印所在行
grep -i 5 Aaa aaa.aaa
//打印本行及以下5行
grep -A 5 aaa aaa.aaa
//打印本行及以上5行
grep -B 5 aaa aaa.aaa
//打印本行及上下5行
grep -C 5 aaa aaa.aaa

2.2 文件内容替换

sed -i 's/[old]/[new]/g' [filename]

filename文件中查找old字符串并将其替换为new字符串
例如:

//将asdf.aaa中的ff替换为gg
$ sed -i 's/ff/gg/g' asdf.aaa
//在asdf.aa中查找ff,无结果
$ sed -n '/ff/p' asdf.aaa
//在asdf.aaa中查找gg,发现2.1中两行中的ff已经变成gg
$ sed -n '/gg/p' asdf.aaa
asdfasdgg
gg1

3.在指定文件中查找内容和替换

结合上文中提到的文件名查找和文件内容查找和替换,通过管道符|xargs(可以将管道数据转换成命令行参数)命令,将find命令的输出作为sed的命令行参数,完成指定文件中内容查找和替换的工作。

find [path] -name '[filename]' | xargs sed -n '[text]'

path下查找filename文件,并在这些文件中查找包含text的行并打印

find [path] -name '[filename]' | xargs sed -i 's/[old]/[new]/g'

path下查找filename文件,并将这些文件中old的字符串替换为new
提示:/等符号需要转义符
例如:

//查找当前目录及子目录中的.launch文件,并将其中包含/robots/字符串的行打印出来
find . -name '*.launch' | xargs sed -n '/\/robots\//p'
//查找当前目录及子目录中的.launch文件,并将其中包含/robots/的字符串替换为/urdf/
find . -name '*.launch' | xargs sed -i 's/\/robots\//\/urdf\//g'

4.将内容另一个文件的指定行后面

4.1 直接插入

sed -i '/[insert_position]/a[insert_text]' [filename]

insert_text插入到filename文件中insert_position的下一行,其中插入到下一行是由/a决定的,/a后面再加一个反斜杠\好像也没什么影响,但是看起来能清楚一些。秉持着能用就行的态度,不去追究太深。如果要插入多行的文字,就在换行时加个\n就好。举个栗子:

//在aaa.aaa文件中的aaa111所在行的下一行插入bbb222和ccc333
sed -i '/aaa111/abbb222\nccc333' aaa.aaa

4.2 将文件内容插入另一个文件的指定行后面

这里多说两句,这个问题的实际应用场景就是同事用Solidworks导出的URDF模型需要仿真,我需要将一些模型插入他的urdf里,上面4.1的方法就很麻烦了。

sed -i '[行号]r 内容所在的文件' [要被插入内容的文件]

例如:

//讲bbb.bbb的内容插入在aaa.aaa的第三行后面
sed -i '3r bbb.bbb' aaa.aaa

5.实现if判断执行

5.1 if的语法

关于shell中if使用的很全的参考链接

//一般模式
if [ condition ]; then
  //command
fi

注意在[后面和]前面都必须要有空格,其他注意事项见上面的链接

5.2实现根据文本内容是否存在判断是否执行插入文本命令

这里承接4中的文件文本插入,需要先判断之前是否插入过,如果已经执行过插入文本的操作就不要再次执行。因为sed和awk命令无论是否检索到要求的值,返回值都为0,所以命令不能够作为逻辑判断的条件,遂使用2.1.2中的grep命令。
grep命令返回值:0成功,1规则未找到,2文件未找到
可使用#?获取上一条命令的返回值,作为判断条件
例如:

#[ INT1 -eq INT2 ] INT1和INT2两数相等返回为真 ,=
#[ INT1 -ne INT2 ] INT1和INT2两数不等返回为真 ,<>
grep aaa111 aaa.aaa
#判断上一条的返回值是否为0
if [ $? -eq 0 ]; then
  echo "aaa111 found"
fi

最后完成任务的成品脚本为

#!/bin/sh
#设定变量var=elevator11
var='elevator11'
#进入目录
cd ~/catkin_ws/src/$var
#在.launch文件中查找'/robots'并替换为'/urdf/'
find . -name '*.launch' | xargs sed -i 's/\/robots\//\/urdf\//g'
#在package.xml文件中查找'me2email'并替换为'me@email'
find . -name 'package.xml' | xargs sed -i 's/me2email/me@email/g'
#在.launch文件中查找'elevator11/urdf.rviz'替换为'/home/xcy/tree.rviz'
find . -name '*.launch' | xargs sed -i 's/$(find "$var")\/urdf.rviz/\/home\/xcy\/tree.rviz/g'
#在elevator11.urdf中查找字符串'world'
grep world urdf/$var.urdf
#如果不存在,则插入文件中的内容
if [ $? -ne 0 ]; then
sed -i '2r /home/xcy/world.urdf' urdf/$var.urdf
fi
  • 6
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值