Snažím se přijít na to, jak replikovat jeden rozsah řádků v textovém souboru. Rozsah začíná řádkem, který je v souboru jedinečný, ale končí řádkem, který může existovat na více místech v souboru.
Zde je několik příkladů vstupu, které musím zpracovat:
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.
Řádky, které potřebuji duplikovat a upravit, jsou tučně, abych na ně zde upozornil.
Výstup, který potřebuji, je:
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.
Dodatečný výstup je tučně, aby to bylo jasné.
Potřebuji získat rozsah řádků začínající řádkem:
This is a unique line
a končí řádkem:
Common
Tento rozsah řádků musí být vložen těsně před původní rozsah řádků. Kopie shodného rozsahu řádků bude muset být mírně upravena.
Řádek „Common“, který ukončuje rozsah, se může vyskytovat na mnoha místech v souboru.
Přišel jsem s funkčním awk
skript, ale zdá se mnohem komplikovanější, než by bylo potřeba. Můj awk
dovednosti neexistují.
/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 }
Existuje čistší a méně podrobný způsob, jak to implementovat? Jsem otevřen dalším možnostem kromě awk
. Musí to být pouze standardní příkaz dostupný v systému macOS.
Přijatá odpověď:
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
Zde je sed
kód (ukázal jsem v sekci Odpověď) přeložený do awk
.
Všimněte si, že kód, který máte, přebíráte odpovědnost za zapnutí/vypnutí awk
variabilní příznak pro sledování linek. Ale zatímco awk
už to za vás pod kapotou dělá přesně to samé, když používáte jeho range
operátor ,