Ich versuche herauszufinden, wie man einen einzelnen Zeilenbereich in einer Textdatei repliziert. Der Bereich beginnt mit einer Zeile, die in der Datei eindeutig ist, aber der Bereich endet mit einer Zeile, die an mehreren Stellen in der Datei vorhanden sein kann.
Hier ist eine Beispieleingabe, die ich verarbeiten muss:
I have no imagination so this sample text will Common be boring. But it does demonstrate the problem I am trying to solve. Common Hi mom! This is a unique line. And here is some more text that should be copied as well. Common Followed by text that should not be copied.
Die Zeilen, die ich duplizieren und ändern muss, sind fett gedruckt, um sie hier hervorzuheben.
Die Ausgabe, die ich brauche, ist:
I have no imagination so this sample text will Common be boring. But it does demonstrate the problem I am trying to solve. Common Hi mom! This is a changed line. And here is different more text that should be copied as well. Common This is a unique line. And here is some more text that should be copied as well. Common Followed by text that should not be copied.
Die zusätzliche Ausgabe ist zur Verdeutlichung fett gedruckt.
Ich muss den Zeilenbereich erhalten, der mit der Zeile beginnt:
This is a unique line
und endet mit der Zeile:
Common
Dieser Zeilenbereich muss unmittelbar vor dem ursprünglichen Zeilenbereich eingefügt werden. Die Kopie des übereinstimmenden Zeilenbereichs muss leicht modifiziert werden.
Die „Common“-Zeile, die den Bereich beendet, kann selbst an vielen Stellen innerhalb der Datei vorkommen.
Ich habe mir ein funktionierendes awk
ausgedacht Skript, aber es scheint viel komplizierter zu sein, als es sein muss. Mein awk
Fähigkeiten sind nicht vorhanden.
/This is a unique line/{flag=1}
/Common/{
if (flag > 0) {
n=m;
sub("some","different",n);
sub("unique","changed",n);
print n "\n" $0 "\n" m;
m=""
};
flag=0
};
flag{
if (length(m) > 0) {
m=m "\n" $0
} else {
m=$0
}
}
!flag{ print }
Gibt es eine sauberere, weniger ausführliche Möglichkeit, dies zu implementieren? Ich bin offen für andere Optionen außer awk
. Es muss nur ein unter macOS verfügbarer Standardbefehl sein.
Akzeptierte Antwort:
awk '/This is a unique line/,/Common/{
H = H RS $0
if ( $0 ~ /Common/ ) {
g = H
sub("\n","",g)
sub("some","different",g)
sub("unique","changed",g)
$0 = g H
} else { next }
}1' inputfile
Hier ist der sed
Code (zeigte ich im Antwortabschnitt) übersetzt in awk
.
Beachten Sie, dass Sie mit dem Code, den Sie haben, die Verantwortung für das Ein- und Ausschalten von awk
übernehmen Variables Flag, um Zeilen zu verfolgen. Aber während awk
tut es unter der Haube bereits für Sie, wenn Sie seinen range
verwenden Operator ,