前几天遇到了一个问题,需要处理一些文本,处理要求如下:

文本每一行中都是相同的两个部分,现在想把第一个部分格式由原来的CamelWord的格式更改为CAMEL_WORD的形式。第二部分不变。如下:

处理前的文档:

HelloWorld HelloWorld
DoSomethingSpecial DoSomethingSpecial
EnglishConditionAction EnglishConditionAction
ThisIsASentenceForTesting ThisIsASentenceForTesting

处理后的文档:

HELLO_WORLD HelloWorld
DO_SOMETHING_SPECIAL DoSomethingSpecial
ENGLISH_CONDITION_ACTION EnglishConditionAction
THIS_IS_A_SENTENCE_FOR_TESTING ThisIsASentenceForTesting

也即,每一行的文本的第一部分由原来的每个单词首字母大写的形式更改为全部大写,并且单词与单词之间使用下划线(_)分隔。

一开始,我是使用vim来做的,不过实在没找到太好的方法,只好先分成两部分。将每一行的第一个部分单独拿到一个文档A当中,然后单独处理那个文档A,再将处理结果合并到只含第二部分的文档B当中。 后来觉着这个方法太费力,所以去求助了CU shell版的大神们,得到了一些比较不错的方法,此处做个记录,以备后查。同时感谢所有提供答案的网友。【此处留待补充更好的vim解决方案】

1. perl脚本方法

感谢jason680提供perl解决方法,其命令如下:

perl -lape '$F[0]=~s/([A-Z][a-z]*)/_\U${1}/g;$_="@F";s/^_//' FILE

我基本没怎么学过perl,这儿简单解释一下命令的意思。以免后面查看起来比较费劲。 解释可能不到位或者有错误,后面熟悉Perl后再回来补充。

命令的四个参数先不管,只看表达式里面的部分。整个表达式以";"为界分为3部分(并以第一行的处理为例给出处理前后的文本示例):

第1部分: ’$F[0]=~s/([A-Z][a-z]*)/_\U${1}/g‘ 我的理解是将每一行的第一部分使用s命令替换,将每个大写字母前面加一个下划线(_),并将整个第一部分所有的字母转换为大写。第一行文本处理后 $F[0] 的内容为:_HELLO_WORLD

第2部分:$_="@F" 将数组的内容赋给$_(Perl的默认输入/输出), $_的内容为:_HELLO_WORLD HelloWorld

第3部分: s/^_// 将开头的下划线(_)删除(因为没有指定对谁做替换处理,所以默认为$_), 之后$_的内容为 HELLO_WORLD HelloWorld

2. sed脚本方法

有多位网友提供sed的解决方法,分别如下:

a. 感谢yinyuemi 提供,命令如下:

sed -r ':a;s/([[:upper:]][[:lower:]]*)([[:upper:] ].+)\1/\1\n\2\1/;ta;:b;s/([^\n ]+)\n(.+)/\U\1_\E\2/;tb;s/_ / /' file

我暂时还没有仔细分析这个命令表达式,会在之后补充说明。

b. 感谢liion631818提供,命令如下:

sed -r 's/ /\n/; h;s/[A-Z]/_&/g;s/.*/\U&/;s/^_//g;G;s/\n.*\n/ /'  file

大致说一下表达式的意思:

对每一行(以第一行为示例):

将空格替换为'\n', (HelloWorld\nHelloWorld)

将替换后的内容存储到hold space当中

将pattern space当中的所有大写字母前添加下划线(_) (_Hello_World\n_Hello_World)

将pattern space当中的所有字符替换为大写;(_HELLO_WORLD\n_HELLO_WORLD)

之后将hold space当中的内容追加到pattern space当中(_HELLO_WORLD\n_HELLO_WORLD\nHelloWorld\nHelloWorld)

将开头的下划线删除(HELLO_WORLD\n_HELLO_WORLD\nHelloWorld\nHelloWorld)

将第一个‘\n'到最后一个'\n'之间的内容替换为空格(HELLO_WORLD HelloWorld)

3. awk脚本方法

同样有多位网友提供awk的解决方法,分别如下:

a. 感谢聆雨淋夜提供,命令如下:

awk '{$1=gensub(/[[:upper:]]/,"_&","g",$1);$1=toupper($1);sub(/_/,"")}1' file

命令比较容易理解,我大致说明一下(以第一行内容示例)

将第一个字段中的所有大写字母前加上下划线,并重新赋给$1, 即(_Hello_World HelloWorld)

将$1的内容全部转为大写,即(_HELLO_WORLD HelloWorld)

删除$0的第一个下划线,即(HELLO_WORLD HelloWorld)

b. 感谢zxy877298415提供,命令如下:

awk '{split($1,a,"");printf a[1];for(i=2;i<=length(a);i++){if(a[i]~/[[:upper:]]/) {printf "_"a[i]} else {printf toupper(a[i])}}print " "$2}' file

命令大致说明:

将第一个字段分割为单个字符组成的数组a

打印a数组的第一个元素

从a数组的第二个元素开始,如果是大写字母,那么在其前面加前导下划线后输出;如果不是大写字母,将转为大写字母输出

循环完成后,打印空格和第二个字段

c.感谢 LikeLx提供,命令如下:

awk '{gsub(/\B[[:upper:]]/,"_&",$1);print toupper($1),$2}' file

命令大致说明:

跟a方法当中方法基本一致,但是此处使用\B这个来界定第一个字段当中仅仅那些前面有字符的大写字母我们才给其加上下划线,行首的字符即使是大写字符,但是由于不满足\B这个条件,所以不再添加下划线。这样就避免了,我们全部添加下划线后,在使用sub去删除的问题。

vim方法

【2015.01.10 16:13更新】

终于想到了一个vim解决方案,虽然应该也还是不完美,但是可以实现了,不过需要两个命令来实现,这个应该可以录制宏或者使用vim脚本的形式来完成。

%s:\(\w\)\@<=\(\([A-Z][a-z]*\)\+ \)\@=:_:g
%s:.* \ze.*:\U&:

简单解释一下:

第一条命令:

匹配符合条件的位置: 前面有字符,后面是大写字母,并在该位置添加下划线(_), 另外为保证仅仅匹配空格前的部分,对于第二部分不影响,所以在

\(\([A-Z][a-z]*\)\+ \)

处"+"号后面有一个空格

第二条命令,是将空格前面的全都转为大写字母。

文本中每行的部分文本格式由CamelWord的形式替换为CAMEL_WORD的形式相关推荐

  1. 如何用python读取文本中指定行的内容

    如何用python读取文本中指定行的内容 搜索资料 我来答 分享 新浪微博 QQ空间 浏览 5284 次 查看全文 http://www.taodudu.cc/news/show-64036.ht ...

  2. python excel处理重复行并统计个数_python统计一个文本中重复行数的方法

    python统计一个文本中重复行数的方法 这篇文章主要介绍了python统计一个文本中重复行数的方法,涉及针对Python中dict对象的使用及相关本文的操作,具有一定的借鉴价值,需要的朋友可以参考下 ...

  3. python统计重复的数_python统计一个文本中重复行数的方法

    本文实例讲述了python统计一个文本中重复行数的方法.分享给大家供大家参考.具体实现方法如下: 比如有下面一个文件 2 3 1 2 我们期望得到 2,2 3,1 1,1 解决问题的思路: 出现的文本 ...

  4. html代码文本框首行缩进,如何将HTML页面中的文本设置首行缩进,文本首行缩进...

    如何将HTML页面中的文本设置首行缩进,文本首行缩进 text-indent属性介绍 属性值单位 描述 em 比如:1em 就代表缩进1个字,2em缩进2个字...... 由于简单我就不过多的介绍了直 ...

  5. java 只显示文本文件_Java设计并实现一个应用程序,能够读取一个文本文件中的内容并显示,同时能够计算出文本中的行数。...

    展开全部 java编写显示文本的应用程序, 需要用到图形界面GUI编程技术. 步骤一: 需要搭建一个整体的外观32313133353236313431303231363533e4b893e5b19e3 ...

  6. shell脚本修改文本中匹配行之前的行的方法

    原创文件,欢迎阅读,禁止转载. 例子中是把 finish 前一行的 "yes" 改成 "YES" 有一个方法就是利用sed+awk一起来完成. zjk@zjk: ...

  7. python随机打乱一个文本中每行数据

    如果你有一个文本,其中有很大数据,每行为一条数据,按照某种顺序进行着排列,出于某种目的,你需要将所有的数据顺序进行随机打乱. 可以用如下python代码瞬间实现: import randomout_f ...

  8. linux查看单词个数,Linux怎么统计文本的的行数/单词数和字符数?

    Linux怎么统计文本的的行数/单词数和字符数? Linux系统中想要统计文本的行数.单词和字符数量,该怎么统计呢?我们可以使用SecureCRT来统计,下面我们就来看看详细的教程. 1.启动Linu ...

  9. python读文件一次读特定行_Python3实现从文件中读取指定行的方法 python读取文本内每行指定内容...

    如何用python读取文本中指定行的内容在这个世界上说不出口的话太多了,你能不能陪小编去,你能不能留下来,你能不能帮帮小编,你对小编很重要,所以你可不可以不要走,到最后哽咽出口的却是,没关系,小编可以 ...

最新文章

  1. 蚂蚁某程序员吐槽前端招人难:一是因为要求高,二是因为招聘卷!网友却说:十万月薪也不去阿里!...
  2. 第八章 Health Check
  3. python读写、创建 文件(一)
  4. 数据可视化:常用图表使用总结
  5. Online开发初体验——Jeecg-Boot 在线设计流程
  6. Markdown语法--整理
  7. java rest 序列化_Django Rest Framework中的序列化和反序列化
  8. python s append_Python Pandas Series.append()用法及代码示例
  9. 解决win7检测不到第二个显示器的方法
  10. 计算机管理禁用usb,电脑如何禁用U盘、怎样禁用USB存储工具,防止USB端口泄密?...
  11. blink usb无线网卡驱动 linux,blink随身wifi驱动
  12. wordpress php7 兼容_WordPress升级PHP7后wp-code-highlight插件兼容性解决方法
  13. VB中的ByVal和ByRef的区别
  14. Qt常见make编译错误:/usr/bin/ld:cannot find -lxxx
  15. i++是线程安全的吗
  16. 领导者/追随者(Leader/Follower)
  17. android在体检报告叫什么,体检报告助手app下载-体检报告助手v3.1.5 安卓版-腾牛安卓网...
  18. 在线计算过往日期天数,计算活了多少天
  19. webservice-CXF3.0
  20. Python ***whl is not a supported wheel on this platfo(Django安装MySQLclinet)

热门文章

  1. 月入过万——网店推广实战方法(第2版)
  2. Fun with Unit Tests – Testing abstract classes
  3. 计算机学校教师培训方案,教师培训电脑多媒体实施方案
  4. 键盘点击事件 vue iview ui
  5. c 语言switch结尾,C存在fall through的switch语句
  6. 原创短视频的美好时代,美拍连出两招加速达人变现
  7. 2021-2027全球及中国燃料电池驱动系统行业研究及十四五规划分析报告
  8. 一个公众号,多个商户ID绑定
  9. 针对大学城的二手书市场
  10. SyntaxError: Non-ASCII character ‘\xe9‘ in file dun.py on line 4