问题
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 :
- remove the text
objectMap.getIdentifier
- 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 literalobjectMap.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