文章目录
前言
shell中有很多文本类的命令特别强大,比如sed cut grep awk等,直接对文本内容进行修改时我们会经常使用sed -i,但是也可能会遇到需要插入的数据不规则,尝试使用sed命令行直接编辑的时候出现各种稀奇古怪的问题(问就是我遇到了)。。。
若有很多文件需要在同样(相同的行号 或 可使用grep等匹配出确定的行号)的位置添加相同的内容,但是sed又行不通,使用逐个文件打开文件并定位至需修改位置难免过于繁琐,出错或遗漏的概率也比较大,下面推荐一个小技巧,希望对大家有所帮助,或者看完图一乐~
一、数据准备
准备10个数据文件 (内容为"how do you do"四个单词分四行显示,前面加一个和文件名末尾相同的数字)
for i in `seq 10`
do
echo "$i how
$i do
$i you
$i do" > multi_edit_${i}.txt
done
二、快速定位修改单文件
1. 定位待修改位置
此处以要在"you"所在行后添加一行新内容为例
# you 所在行号获取
$ grep -n 'you' multi_edit_7.txt | cut -d: -f1
3
2. 使用 vim file_name +line_number
语法打开文件并直接定位到需修改位置
$ vim multi_edit_7.txt +3
三、批量修改文件
1. 编写修改单文件的函数
关于函数使用可参照博客:
shell中三种函数定义方式
# 定义函数
$ function medit(){
# grep -n 的作用是显示行号, 在行首显示, 与后面的内容以":"分隔
# cut -d 的作用是指定分隔符 -f1 表示取第一列内容, 即上面匹配的行号
no=`grep -n 'you' $1 | cut -d: -f1`
# 进入编辑前建议打印一下文件名 方便后期核查
echo $1
# 此函数只需传 文件名 一个参数
vim $1 +$no
}
# 测试修改单个文件
$ medit multi_edit_6.txt
2. 使用循环和medit函数连续修改批量文件
# `ls | grep multi`可匹配到当前所有10个文件
# 此处不要使用 `| while`的循环方式, 因为while是在子shell中执行的,可能无法获取到当前shell临时定义的medit函数
$ for f in `ls | grep multi`
do
medit $f
done
其他
1. 如果you在文中出现多次,且都需要进行修改,但vim +的方式一次只能指定一个行号,所以在上述函数中,需在cut后使用 head -n | tail -1的方式依次取出行号,然后依次进行修改。
2. 当然,你可能会说sed本身就支持命令行直接对文本内容进行修改,可参考:
sed删减行
但此处讨论此"蹩脚"方法的原因,是工作中需要修改三十多个数据导出脚本,需要在两处分别增加三行,而且三行内容包含$ { "等特殊字符,也尝试过转义然后代入sed命令行进行修改,但始终不如人意。
提示
希望大家测试的时候尽量用没用的文件,或者使用章节一中的方法简单生成几个样例文件
修改正式文件的时候还是建议先备份一下,有备无患