摘要: 使用 Sed 完成文本替换操作任务是非常合适的。结合 find 命令,即可实现指定批量文件的文本替换。同时给出了Awk的解决方案作为对比。

问题

现在, 我要将一个原有Java项目中的一些包及下面的类移到另一个Java项目中复用(一个实际场景是,将自己工具箱的常用框架、工具包及类挪到具体项目中使用)。

Project javastudy:

Packages:

algorithm/ ,  foundations/,  javatech/, patterns/, threadprogramming/, datastructure/, javagui/, junitest3/, testdata/,  utils/

这些包下面会有很多子包。

现在要把这些包及其子包下面的所有 Java 文件移动到 Project ALLIN, 放在 package:  zzz.study 下面。

思路

在尝试使用 Eclipse 包重构无效之后, 我还是采用了最直观的方案: 将 Project javastudy 的上述包直接复制到 Project ALLIN 的包 zzz.study 下面。 复制之后, 要解决一个问题是: 必须手动更改每个 Java 文件的 package , import 引用。 比如 algorithm/BitsMapSort.java 中

package algorithm.sort;

import java.util.Arrays;
import datastructure.vector.NBitsVector;  

必须改成:

package zzz.study.algorithm.sort;

import java.util.Arrays;
import zzz.study.datastructure.vector.NBitsVector;

也就是说, 要将指定包的多个Java文件里的 package packageName 和 import packageName 批量替换成 package zzz.study.packageName ,  import zzz.study.packageName, 其中 packageName 取以下这些值: algorithm ,  foundations,  javatech, patterns, threadprogramming, datastructure, javagui, junitest3, testdata,  utils 。

Sed解决方案

难道真的要手动修改这么多文件的包和导入引用么?

于是想到了使用Sed. 注意到, 关键是匹配到 package|import packageName 即可。 可以使用分组和引用来完成。 命令如下:

sed -r -i 's/(package|import) (algorithm|foundations|javatech|patterns|threadprogramming|datastructure|javagui|junitest3|testdata|utils)(.*)/\1 zzz.study.\2\3/'

要批量完成多个文件的上述操作, 使用 find | xargs 即可:

find . -name "*.java" | xargs sed -r -i 's/(package|import) (algorithm|foundations|javatech|patterns|threadprogramming|datastructure|javagui|junitest3|testdata|utils)(.*)/\1 zzz.study.\2\3/'

Awk解决方案

显然,有了 find 命令,只要处理好单个文件的文本替换,然后使用 for 循环依次处理即可。 awk 处理单个文件的文本替换如下代码所示。 ARGV[1] 是传入的文件名,通常生成一个临时文件然后去覆写原来的文件,获得就地修改的效果。system 用来调用 shell 命令,挺好的特性。 ~ 用于匹配行是否满足某种条件。awk -f replace.awk BitsMapSort.java 用指定的 awk 程序 replace.awk 来处理指定文件 BitsMapSort.java。

$ cat replace.awk

$ awk -f replace.awk BitsMapSort.java

BEGIN {
origin_filename = ARGV[]
print origin_filename
filename = origin_filename".tmp"
}
{
if ($ ~ /^(package|import) (algorithm|foundations|javatech|patterns|threadprogramming|datastructure|javagui|junitest3|testdata|utils).*/) {
print $" zzz.study."$ >> filename
}
else {
print $ >> filename
} }
END {
cmd = "mv "filename" "origin_filename
system(cmd)
}

批量处理文件替换的命令是:

for file in $(find . -name '*.txt'); do awk -f replace.awk $file;  done

小结

本文分别使用Sed和Awk两个小工具来实现批量文件的文本替换。可以看到 Sed 由于具备就地修改的特性,比 Awk 实现要简洁的多。为什么还要使用Awk来实现呢? 一个重要原因是期望拥有多种解决途径和视角,不局限于单一方案。Awk 在规则的记录文件处理可以显示出更强大的威力,而Sed在任意文本内容替换上更具优势。

Sed 用法参考文章:

1.  Linux 之 Sed 用法

2.  Sed替换

3.  Sed命令的工作原理

4.  Sed&Awk 读书笔记之Sed

5.  sed高级用法:模式空间(pattern space)和保持空间(hold space)

Sed文本替换一例的更多相关文章

  1. sed 技巧一例:特定位置插入

    通过一例子熟悉 sed 的运用 下面命令是在修改 ~/fs/install/nzos.conf 文件, 并在 env 第一次出现的地方再添加一行 env LXC_EXTRA_PORT=5556 sed ...

  2. sed awk 样例

    sed [options] '[action]' filename options: -n:一般sed命令会把所有数据都输出到屏幕,如果加入此选项,则只会把经过sed命令处理的行输出到屏幕. -e:允 ...

  3. sed awk 小例

    实现数据库批量更新与回滚 create database awktest; use awktest create table user(    id int unsigned not null uni ...

  4. 《sed的流艺术之二》-linux命令五分钟系列之二十二

    本原创文章属于<Linux大棚>博客,博客地址为http://roclinux.cn.文章作者为rocrocket. 为了防止某些网站的恶性转载,特在每篇文章前加入此信息,还望读者体谅. ...

  5. [svc]linux正则实战(grep/sed/awk)

    企业实战: 过滤ip 过滤出第二行的 192.168.2.11. eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 ine ...

  6. Linux Shell 文本处理工具集锦--Awk―sed―cut(row-based, column-based),find、grep、xargs、sort、uniq、tr、cut、paste、wc

    本文将介绍Linux下使用Shell处理文本时最常用的工具:find.grep.xargs.sort.uniq.tr.cut.paste.wc.sed.awk:提供的例子和参数都是最常用和最为实用的: ...

  7. sed和awk的简单使用

    sed是一个很好的文件处理工具,本身是一个管道命令,主要是以  行 为单位进行处理,可以将数据行进行替换.删除.新增.选取等特定工作,下面先了解一下sed的用法. 语法: sed [-nefri] ‘ ...

  8. Linux三剑客之sed流编辑器

    一.功能说明 Sed是Stream Editor(流编辑器)缩写,是操作.过滤和转换文本内容的强大工具.常用功能有增删改查,过滤,取行. 二.语法格式 Usage: sed [options] [se ...

  9. Shell基础(五):sed基本用法、使用sed修改系统配置、sed多行文本处理、sed综合脚本应用

    一.sed基本用法 目标: 本案例要求熟悉sed命令的p.d.s等常见操作,并结合正则表达式,完成以下任务: 1> 删除文件中每行的第二个.最后一个字符    2> 将文件中每行的第一个. ...

随机推荐

  1. 有了JSON.stringify(),处理json将变得更简单!!

    之前处理json 需要拼接json字符串,但是,如果用上JSON.stringify()的话,忘了json语法以没关系了..... @{ ViewBag.Title = "GetStr&qu ...

  2. PHP for 循环

    <!DOCTYPE html> <html> <body> <?php for ($x=0; $x<=10; $x++) { echo "数字 ...

  3. 敏捷BI——岂止于快

    信息爆炸的时代,唯有分析快,才可以把握住可能分分钟流失的数据信息,唯有钻取深,才可以挖掘出海量信息中蕴藏的财富.是时候为您的企业上一套敏捷BI了. [敏捷BI的产生背景] 传统BI由IT人员做报表,业 ...

  4. Java jaxp查询节点

    <?xml version="1.0" encoding="UTF-8"?> <person> <p1> <name& ...

  5. Go prepare statment超过mysql最大数

    mysql_stmt_prepare failed! error(1461)Can't create more than max_prepared_stmt_count statements (cur ...

  6. docker offical docs:Working with Containers

    enough ---------------------------------------------------------------------------------- Working wi ...

  7. 对jsp可见域的变量感悟

    page  变量当前页面有效 reqeust 某次请求中的变量有效 session 某次会话中的变量有效 application 全站有效 page<request<session< ...

  8. c++l类

    c++类和C#中定义类的方法异同之处: 1. 相同处: 1.1.都需要使用 class标识: 1.2.都包含有成员:函数,属性: 1.3.都有private public protect 标识的成员 ...

  9. 使用Mac的AppleScritp调用控制台的方式

    使用Mac的AppleScritp调用 控制台的方法 tell application "Terminal" activate do script "cd Documen ...

  10. [原创]java WEB学习笔记50:文件上传案例

    本博客为原创:综合 尚硅谷(http://www.atguigu.com)的系统教程(深表感谢)和 网络上的现有资源(博客,文档,图书等),资源的出处我会标明 本博客的目的:①总结自己的学习过程,相当 ...