0.sed -i与sed

sed -i 就是直接对文本文件进行操作的,如果单纯是sed那么就只是把处理结果输出到命令行,实际上文件内容没有变化。

动作说明: [n1[,n2]]function
n1, n2 :不见得会存在,一般代表『选择进行动作的行数』,举例来说,如果我的动作是需要在 1020 行之间进行的,则『 10,20[动作行为] 』

-i :直接修改读取的文件内容,而不是输出到终端。
-s :取代,可以直接进行取代的工作哩!通常这个 s 的动作可以搭配正规表示法!例如 1,20s/old/new/g 就是啦!

1.修改文件内容

参考:Ubuntu设置CMake编译时使用的OpenCV版本

比如CMakeLists.txt文件内容如下:

cmake_minimum_required(VERSION 3.1)
project(test)

find_package(OpenCV REQUIRED)
file(GLOB_RECURSE sources src/*.cpp)
add_exectuable(${PROJECT_NAME} SHARED ${sources})
target_link_libraries(
    ${PROJECT_NAME}
    ${OpenCV_LIBS}
)

使用如下命令替换OpenCV REQUIREDOpenCV 3 REQUIRED

sed -i "s/OpenCV REQUIRED/OpenCV 3 REQUIRED/g" CMakeLists.txt

2.在文件中插入行

参考:【Linux】在文件的指定位置插入数据

在1中替换后,CMakeLists.txt文件内容如下,cat -n参数代表输出显示行号。

# cc @ home-pc in ~/Desktop [0:18:24]
$ cat -n CMakeLists.txt
     1	cmake_minimum_required(VERSION 3.1)
     2	project(test)
     3	
     4	find_package(OpenCV 3 REQUIRED)
     5	file(GLOB_RECURSE sources src/*.cpp)
     6	add_exectuable(${PROJECT_NAME} SHARED ${sources})
     7	target_link_libraries(
     8	    ${PROJECT_NAME}
     9	    ${OpenCV_LIBS}
    10	)

通过sed -i "行数+i+空格+想要插入的语句" 想要插入的文件名 来插入,注意插入的行数是指从哪行插入。比如想从第5行插入message(STATUS "OpenCV_DIR = "${OpenCV_DIR}")这句话,如下所示。

注意

  1. 内部"要用转义字符\进行转义。
  2. 内部$也要用转义字符\进行转义,因为现在是命令行输入,会自动把$字符认为是查找环境变量。
# cc @ home-pc in ~/Desktop [0:19:25] C:130
$ sed -i "5i message(STATUS \"OpenCV_DIR = \${OpenCV_DIR}\")" CMakeLists.txt

# cc @ home-pc in ~/Desktop [0:28:24] 
$ cat -n CMakeLists.txt       
     1	cmake_minimum_required(VERSION 3.1)
     2	project(test)
     3	
     4	find_package(OpenCV 3 REQUIRED)
     5	message(STATUS "OpenCV_DIR = ${OpenCV_DIR}")
     6	file(GLOB_RECURSE sources src/*.cpp)
     7	add_exectuable(${PROJECT_NAME} SHARED ${sources})
     8	target_link_libraries(
     9	    ${PROJECT_NAME}
    10	    ${OpenCV_LIBS}
    11	)

3.在文件中删除行

参考:运用sed命令高效地删除文件的特定行

  • 删除第N行
sed -i 'Nd' file.txt
# 比如删除第一行:
sed -i '1d' file.txt
  • 删除最后一行
# $符号代表最后一行
sed -i '$d' file.txt
  • 删除从A到B连续几行
sed -i 'A,Bd' file.txt
# 比如删除5~7行:
sed -i '5,7d' file.txt

还有很多其他用法,见上面的参考博客

4.使用find查找文件,并用 | xargs传输文件名给sed命令

比如要在当前文件夹下找名为CMakeLists.txt的文件,找到后对他们使用sed命令进行内容修改。

  • 查看当前文件夹下哪些文件中有“OpenCV REQUIRED”(无用)
# -r代表递归搜索当前文件夹下的文件内容
grep -r "OpenCV REQUIRED"
  • 查看有哪些“CMakeLists.txt”文件(无用)
# -i参数代表不区分后面文件名的大小写查找
find ./ -iname "CMakeLists.txt"
  • 把“CMakeLists.txt”文件中原来的“OpenCV REQUIRED”统一替换成“OpenCV 3 REQUIRED”(实用)
# xargs是传递参数,好像和管道|有点重复?
find ./ -iname "CMakeLists.txt" | xargs sed -i "s/OpenCV REQUIRED/OpenCV 3 REQUIRED/g"

xargs是一个强有力的命令,它能够捕获一个命令的输出,然后传递给另外一个命令。

之所以能用到这个命令,关键是由于很多命令不支持|管道来传递参数,而日常工作中有有这个必要,所以就有了 xargs 命令,例如:

find /sbin -perm +700 |ls -l       #这个命令是错误的
find /sbin -perm +700 |xargs ls -l   #这样才是正确的

xargs 一般是和管道一起使用。

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐