摘要: 使用 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. Linux绑定双网卡

    Linux绑定双网卡 1. 配置参数文件 版本在centos6以下在/etc/modproe.conf文件中配置,版本是centos6.x或以上在/etc/modproe.d/目录下配置. 2.    ...

  2. 3.Python编程语言基础技术框架

    3.Python编程语言基础技术框架 3.1查看数据项数据类型 type(name) 3.2查看数据项数据id id(name) 3.3对象引用 备注Python将所有数据存为内存对象 Python中 ...

  3. 腾讯企鹅智酷100多张PPT:移动时代创业黄金法则

    移动时代创业黄金法则 http://tech.qq.com/a/20141223/008325.htm#p=8

  4. getconf 命令

    getconf 命令 用途 将系统配置变量值写入标准输出. 系统的默认参数,比如mkfs读取默认参数,并格式化,默认PAGESIZE是4096 语法 getconf [ -v specificatio ...

  5. 第十篇 Integration Services:高级事件行为

    本篇文章是Integration Services系列的第十篇,详细内容请参考原文. 简介在前一篇, we introduced fault tolerance by examining method ...

  6. ios9 升级后 企业版app plist无法安装

    昨天apple推送了ios9, 公司的一些app是企业版的,平常通过 item-service 结果更改如下 plist可以了 itms-services://?action=download-man ...

  7. Oracle 12C -- 使用seed PDB创建新的pdb

    $ sqlplus '/as sysdba' SQL*Plus: Release Production on Tue Jun :: Copyright (c) , , Oracle. All righ ...

  8. 数据库调优过程(一):SqlServer批量复制(bcp)[C#SqlBulkCopy]性能极低问题

    背景 最近一段给xx做项目,这边最头疼的事情就是数据库入库瓶颈问题. 环境 服务器环境:虚拟机,分配32CPU,磁盘1.4T,4T,5T,6T几台服务器不等同(转速都是7200r),内存64G. 排查 ...

  9. JMX超详细解读

    一.JMX的定义 JMX(Java Management Extensions)是一个为应用程序植入管理功能的框架.JMX是一套标准的代理和服务,实际上,用户可以在任何Java应用程序中使用这些代理和 ...

  10. win7无线网连接了,但是图标显示未连接

    第一步: 打开控制面板,找到“管理工具”->“计算机管理” 第二步: 在控制台左边栏,选择“设备管理器”,然后在右侧展开“网络适配器” 第三步: 在每一个网络设备上点鼠标右键,然后选择“卸载”. ...