sed command to replace dots

耗尽温柔 提交于 2020-06-27 18:36:12

问题


I have a number of scripts, in which i want to scan a particular type of string, and replace dots in those strings alone. We are replacing our locator strategy from map to something else, so the variables have to be changed from having dots to having underscore

In the below, I want to change

driver.click(objectMap.getIdentifier(new.dropdown), "DropDown clicking");

TO

driver.click(new_dropdown, "DropDown clicking");

So 2 things :

  1. remove the text objectMap.getIdentifier
  2. Replace the enclosed string from having dots to underscore

If I try to use sed 's/./_/g' >> This will replace all the dots across, I want to replace only the dots which are enclosed within objectMap.getIdentifier. Tried these sed commands, but not of much use : sed -e 's/objectMap.getIdentifier("\(.*\).\(.*\)")/(\1_\2)/pg'

Example :

import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

    public class TestingScript {
    public void createNewItems(String itemName){
    driver.click(objectMap.getIdentifier(new.dropdown), "DropDown clicking");
    driver.click((objectMap.getIdentifier("new.dropdown.notes.button"), "Note from template");
    driver.click((getElement(objectMap.getIdentifier("modal.default.template").replace("$Template",  "Default")), "Default", true);
    driver.click((getElementByText(templateName), templateName);
    driver.click(objectMap.getIdentifier(new.dropdown), "DropDown clicking");
    driver.click((objectMap.getIdentifier("modal.create.button"), "Create");
  } 
}

回答1:


It's ugly, it's sed,it works (as long as the lines with objectMap.getIdentifier() don't contain #)

#!/bin/bash

sed '
/objectMap\.getIdentifier(/{
    # copy pattern-space to hold-space
      h;
    # replace pattern-space with only the contents inside objectMap.getIdentifier()
      s/^.*objectMap\.getIdentifier(\([^)]*\)).*$/\1/;
    # replace all dots with underscores
      s/\./_/g;
    # swap pattern-space with hold-space
      x;
    # Replace objectMap.getIdentifier(.*) with a "#"
      s/objectMap\.getIdentifier([^)]*)/#/;
    # Append hold-space to pattern-space (with new-line between)
      G;
    # parse out the contents we want, use "#" as key for replacement
      s/^\([^#]*\)#\(.*\)\n\(.*\)$/\1\3\2/
}' ./infile

Proof of Concept

$ sed '/objectMap\.getIdentifier(/{h;s/^.*objectMap\.getIdentifier(\([^)]*\)).*$/\1/;s/\./_/g;x;s/objectMap\.getIdentifier([^)]*)/#/;G;s/^\([^#]*\)#\(.*\)\n\(.*\)$/\1\3\2/}' ./infile
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

    public class TestingScript {
    public void createNewItems(String itemName){
    driver.click(new_dropdown, "DropDown clicking");
    driver.click(("new_dropdown_notes_button", "Note from template....");
    driver.click((getElement("modal_default_template".replace("$Template",  "Default")), "Default", true);
    driver.click((getElementByText(templateName), templateName);
    driver.click(new_dropdown, "DropDown clicking");
    driver.click(("modal_create_button", "Create");
  }
}



回答2:


As per OP input, two requested changes

  • If the key for get_identifier is string literal objectMap.get_identifier("foo.bar.zoo"), the quotes should be removed, and the key should be converted to symbolic name with '_': foo_bar_zoo
  • If the key is a variable objectMap.getIdentifier(new.dropdown), should be converted to _ separated key: new_dropdown

Doing this with sed is tricky, as sed is line oriented. it's hard to limit the scope of the '.' replacement to a single line. I believe Perl will do better here. Not exactly within the constraint of OP (requested sed solution).

The first '-e' define a function to translate a single token ('.' -> '_', remove quotes) The second '-pe' apply the function to the input.

perl -e 'sub fix { $_ = shift ; s/"//g ; s/\./_/g ; return $_  }' -pe 's/objectMap\.getIdentifier\(("?[a-z.]+"?)\)/fix($1)/e' < a.java

Might be easier to create a perl script, doing the same

#! /usr/bin/perl
use strict ;
sub fix { $_ = shift ; s/"//g ; s/\./_/g ; return $_  }

while ( <> ) {
    s/objectMap\.getIdentifier\(("?[a-z.]+"?)\)/fix($1)/e ;
    print ;
}

Output (for sample input). Noticed unbalanced parenthesis, that exists in the input data.

import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

    public class TestingScript {
    public void createNewItems(String itemName){
    driver.click(new_dropdown, "DropDown clicking");
    driver.click((new_dropdown_notes_button, "Note from template");
    driver.click((getElement(modal_default_template.replace("$Template",  "Default")), "Default", true);
    driver.click((getElementByText(templateName), templateName);
    driver.click(new_dropdown, "DropDown clicking");
    driver.click((modal_create_button, "Create");
  } 
}



来源:https://stackoverflow.com/questions/62186387/sed-command-to-replace-dots

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!