2013-06-04 13 views
5

Mam plik, który muszę zmodyfikować. Część, którą muszę zmodyfikować (nie cały plik), jest podobna do właściwości pokazanych poniżej. Problem polega na tym, że muszę tylko zastąpić część "wartości", "Konfigurowalna część", jeśli zechcesz. Otrzymuję ten plik, więc nie mogę kontrolować jego formatu.Potrzebujesz sposobu Groovy na częściowe zastępowanie plików

alpha.beta.gamma.1 = constantPart1ConfigurablePart1 
alpha.beta.gamma.2 = constantPart2ConfigurablePart2 
alpha.beta.gamma.3 = constantPart3ConfigurablePart3 

Wykonałem tę pracę w ten sposób, choć wiem, że jest naprawdę źle!

def updateFile(String pattern, String updatedValue) { 
    def myFile = new File(".", "inputs/fileInherited.txt") 
    StringBuffer updatedFileText = new StringBuffer() 
    def ls = System.getProperty('line.separator') 
    myFile.eachLine{ line -> 
     def regex = Pattern.compile(/$pattern/) 
     def m = (line =~ regex) 
     if (m.matches()) { 
      def buf = new StringBuffer(line) 
      buf.replace(m.start(1), m.end(1), updatedValue) 
      line = buf.toString() 
     } 
     println line 
     updatedFileText.append(line).append(ls) 
    } 
    myFile.write(updatedFileText.toString()) 
} 

Przekazany wzór jest wymagany, aby zawierać grupę podstawioną w StringBuffer. Czy ktoś wie, jak to naprawdę powinno się robić w Groovy?

EDIT - aby określić oczekiwany wynik

plik zawierający przykładowe linie musi być aktualizowany tak, że „ConfigurablePart” z każdej linii jest zastąpiona zaktualizowanym tekstowym. Dla mojego brzydkiego rozwiązania, musiałbym wywołać metodę 3 razy, raz, aby zastąpić ConfigurablePart1, raz dla ConfigurablePart2, a na końcu dla ConfigurablePart3. Prawdopodobnie istnieje lepsze podejście do tego!

* AKTUALIZACJA - Odpowiedź, że zrobił to, co naprawdę potrzebne *

w przypadku innych kiedykolwiek uderzył podobny problem, Groovy ulepszeń kodu Pytałem o najlepiej odzwierciedlone w przyjętym odpowiedź. Jednak z mojego problemu, który nie całkiem rozwiązał moje problemy. Ponieważ musiałem zastąpić tylko część dopasowanych linii, musiałem użyć referencji zwrotnych i grup. Jedynym sposobem mogę dokonać tej pracy było określenie trzyczęściowej regex takich jak:

(.*)(matchThisPart)(.*) 

Gdy to się stało, byłem w stanie używać:

it.replaceAdd(~/$pattern/, "\$1$replacement\$3") 

Dzięki obu odpowiedziach - każdy pomógł mnie bardzo dużo!

+0

Oczekiwany wyjście proszę ... – HamZa

Odpowiedz

6

To może być bardziej gadatliwy z wykorzystaniem Zamknięcie args. Oto w jaki sposób można to zrobić:

//abc.txt 
abc.item.1 = someDummyItem1 
abc.item.2 = someDummyItem2 
abc.item.3 = someDummyItem3 
alpha.beta.gamma.1 = constantPart1ConfigurablePart1 
alpha.beta.gamma.2 = constantPart2ConfigurablePart2 
alpha.beta.gamma.3 = constantPart3ConfigurablePart3 
abc.item.4 = someDummyItem4 
abc.item.5 = someDummyItem5 
abc.item.6 = someDummyItem6 

Groovy Code: -

//Replace the pattern in file and write to file sequentially. 
def replacePatternInFile(file, Closure replaceText) { 
    file.write(replaceText(file.text)) 
} 

def file = new File('abc.txt') 
def patternToFind = ~/ConfigurablePart/ 
def patternToReplace = 'NewItem' 

//Call the method 
replacePatternInFile(file){ 
    it.replaceAll(patternToFind, patternToReplace) 
} 

println file.getText() 

//Prints: 
abc.item.1 = someDummyItem1 
abc.item.2 = someDummyItem2 
abc.item.3 = someDummyItem3 
alpha.beta.gamma.1 = constantPart1NewItem1 
alpha.beta.gamma.2 = constantPart2NewItem2 
alpha.beta.gamma.3 = constantPart3NewItem3 
abc.item.4 = someDummyItem4 
abc.item.5 = someDummyItem5 
abc.item.6 = someDummyItem6 

Potwierdź plik abc.txt. Nie stosować metodę updateFile() jak zrobione przez Ciebie, ale można bardzo dobrze parametryzacji jak poniżej: -

def updateFile(file, patternToFind, patternToReplace){ 
    replacePatternInFile(file){ 
     it.replaceAll(patternToFind, patternToReplace) 
    } 
} 
+1

Sekwencyjnie, nie jednocześnie ;-) –

+0

@tim_yates Dobry połów. Zaktualizowano natychmiastowo. : P – dmahapatro

+0

Ponieważ miałem wiele wzorów, użyłem podejścia Map od pierwszej odpowiedzi jako świetny sposób na dostarczenie Wzorów i Zastąpień do powyższej techniki. – JoeG

3

uzyskać szybką odpowiedź ja właśnie tę drogę:

patterns = [pattern1 : constantPart1ConfigurablePart1, 
    pattern2 : constantPart2ConfigurablePart2, 
    pattern3 : constantPart3ConfigurablePart3] 


def myFile = new File(".", "inputs/fileInherited.txt") 
StringBuffer updatedFileText = new StringBuffer() 
def ls = System.getProperty('line.separator') 
myFile.eachLine{ line -> 
    patterns.each { pattern, replacement -> 
     line = line.replaceAll(pattern, replacement) 
    } 
    println line 
    updatedFileText.append(line).append(ls) 
} 
myFile.write(updatedFileText.toString()) 
+0

Jeśli trzeba to zrobić w miejscu wyglądać franco http: // blog.davidehringer.com/groovy/processing-files-place-groovy/ –

+2

Chciałbym móc sprawdzić obie odpowiedzi, głównie korzystałem z poniższego rozwiązania, ale połączyłem Twoje podejście z wzorcem Map - bardzo ładne - dzięki! – JoeG

Powiązane problemy