GNU/Linux >> Znalost Linux >  >> Linux

Duplicitní, s několika malými změnami, několika řádky v textovém souboru?

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 ,


Linux
  1. Jak posunout řádek v textovém souboru nahoru nebo dolů o jeden řádek?

  2. Vložit nové řádky s chybějícími hodnotami (ne)?

  3. Efektivně odstranit prvních pár řádků z textového souboru?

  1. Smazat po sobě jdoucí řádky v CSV s duplicitními hodnotami v jednom poli, ale ponechat poslední řádek?

  2. Sledování změn Crontabu pomocí Git?

  3. Jak nahradit text podobný sedu pythonem?

  1. Kočičí čára X do čáry Y na obrovském souboru?

  2. echo text s novým řádkem v bash

  3. nahradit řádky v jednom souboru řádky v jiném číslem řádku