在没有计数的元素后插入1

时间:2019-05-09 09:55:28

标签: regex sed

我有一个结构如下的文件:

NH3O
CH4
CHN
C2NOPH3

我试图做的是将1放在两个字母之间或项目结尾处。因此,所需的输出为:

NH3O1
C1H4
C1H1N1
C2N1O1P1H3

到目前为止,我一直在尝试类似sed -e 's/\([A-Z]\)\([A-Z]\)/\11\2/g' -e 's/\([A-Z]\)[[:blank:]]/\11/g'的方法,但这种方法无法解决。

感谢任何提示

2 个答案:

答案 0 :(得分:2)

  • [[:blank:]]与行尾不匹配,但$与行尾匹配,
  • 与其指定g标志,不如使用branching and flow control来实现循环,因为使用g时,sed不会在先前替换的部分上执行替换操作(即,它将保留第二个符号,因为它们是),
  • 还处理长度超过一个字符的符号(即,将小写字符匹配大写字符),
  • 如今并不需要太多,但是坚持POSIX标准并避免实现特定功能将使您的脚本更具可移植性。
sed -e ':1' -e 's/\([[:upper:]][[:lower:]]*\)\([[:upper:]]\|$\)/\11\2/' -e 't1'

答案 1 :(得分:1)

请您尝试遵循,使用GNU awk进行编写和测试。

awk '{num=split($0,array,"");for(i=1;i<=num;i++){if(array[i]~/^[a-zA-Z]*[a-zA-Z]/ && (array[i]+1)~/^[a-zA-Z]*/){array[i]=array[i]"|"};val=val array[i]};print val;val=""}' Input_file

在此处添加非单一衬里形式的解决方案。

awk '
{
  num=split($0,array,"")
  for(i=1;i<=num;i++){
    if(array[i]~/^[a-zA-Z]*[a-zA-Z]/ && (array[i]+1)~/^[a-zA-Z]*/){
      array[i]=array[i]"|"
    }
    val=val array[i]
  }
  print val
  val=""
}
'   Input_file