Távolítsa el a bizonyos karakterláncot tartalmazó sort és a következő sort

Ezt használom

cat foo.txt | sed "/bar/d"

a bar karakterláncot tartalmazó sorok eltávolításához a fájlból.

Szeretném azonban eltávolítani ezeket a sorokat és közvetlenül a sort utána t. Lehetőleg sed, awk vagy más, a MinGW32-ben elérhető eszközben.

Ez egyfajta fordított hogy mit kaphatok a grep fájlban a -A és -B fájlban az egyező sorok kinyomtatásához is mint sorok az illesztett vonal előtt / után.

Van valami egyszerű módja annak elérésére?

Megjegyzések

  • Csak információ: I ' m elemzem azokat a naplókat, amelyekben a bejegyzések kétsorosak. Tehát szeretnék megtalálni a mintának megfelelő bejegyzést, és eltávolítani azt, valamint a következő sort. Ezért nem kell, hogy kezeljem az egymást követő mérkőzési sorokat, de mindenképpen köszönöm a válaszok teljességét!

Válasz <' / h2>

Ha GNU sed van (tehát nem beágyazott Linux vagy Cygwin):

sed "/bar/,+1 d" 

Ha bar van két egymást követő sorban, ez anélkül elemzi a második sort. Például, ha 3 soros fájlja van: bar / bar / foo, a foo sor marad.

Megjegyzések

  • +1 a hosszúságra 🙂 példa Nem ' nincs egymás utáni bar s, így ezt nagyon könnyű megjegyezni.
  • sed '/bar/d' ha " csak egy bizonyos karakterláncot tartalmazó sort akar eltávolítani " és nem a következő.
  • Ha matematika után el akarom távolítani az összes sort?
  • @Pandya Ez ' más. Használhatja pl. sed '/math/q'
  • @ A.K. Ha csak az egyező sort szeretné törölni, akkor ' még egyszerűbb: sed '/bar/d'

Válasz

Ha bar fordulhat elő egymást követő sorokban, akkor ezt teheti:

awk "/bar/{n=2}; n {n--; next}; 1" < infile > outfile 

amely több mint 2 sor törléséhez alkalmazható úgy, hogy megváltoztatja a fenti kettőt a törlendő sorok számával, beleértve a megfelelő sort is.

Ha nem, akkor “könnyen elvégezhetők sed @MichaelRollins” megoldással vagy:

sed "/bar/,/^/d" < infile > outfile 

Megjegyzések

  • Az AWK megoldás másik pluszja, hogy a (z) /bar/ szót helyettesíteni tudom /bar|baz|whatever/. A sed szakaszban ez a szintaxis nem működik úgy, mint '.
  • @ jakub.g, van GNU sed ( v4.4 most). Nem biztos a többiekben. Azt tudom, hogy " basic " reguláris kifejezés szintaxist használja alapértelmezés szerint, ezért a példád nem ' t munka. A kívánt cél elérése érdekében vagy visszahúzhat minden függőleges vonal elé, vagy megkérheti a sed felhasználót, hogy használja a " kiterjesztett " reguláris kifejezések. További információ itt: gnu.org/software/sed/manual/html_node/… . Felhívjuk figyelmét, hogy ez a grep fájlra is érvényes. Itt ' s a saját működő példám: echo $'0a\n1b\n2c' | sed '/0a\|1b/d'.

Válasz

Nem beszélek folyékonyan a sed-ről, de ezt awk-ben könnyű megtenni:

awk "/bar/{getline;next} 1" foo.txt 

Az awk szkript a következõ: a sávot tartalmazó sorhoz szerezzük be a következõ sort (getline), majd hagyjuk ki az összes késõbbi feldolgozást (következõ). Az 1 minta a végén kinyomtatja a fennmaradó sorokat.

Frissítés

Amint a megjegyzésben rámutattunk, a fenti megoldás nem működött egymást követő bar. Itt van egy átdolgozott megoldás, amely figyelembe veszi:

awk "/bar/ {while (/bar/ && getline>0) ; next} 1" foo.txt 

Mostantól folytatjuk az olvasást, hogy kihagyjuk az összes / bar / sort.

Megjegyzések

  • A grep -A 100% -os ismétléséhez tetszőleges számú egymást követő sorok helyesen (a teljes blokk és egy sor eltávolításával).

Válasz

Ehhez ki kell használnia a sed parancsfájljainak képességeit.

$ sed -e "/bar/ { $!N d }" sample1.txt 

Mintaadatok:

$ cat sample1.txt foo bar biz baz buz 

Az “N” parancs a következő beviteli sort fűzi a mintaterülethez. Ez a mintaillesztés (/ bar /) sorával kombinálva lesz az a sor, amelyet törölni szeretne. Ezután törlés a “d” paranccsal.

Megjegyzések

  • Hogyan írhatok be új sort a konzolba? Vagy ez csak szkript?
  • @ jakub.g: GNU-val sed: sed -e '/bar/{N;d}' sample1.txt

Válasz

Ha a mérkőzést közvetlenül követő sorokat el kell távolítani, akkor sed programjának figyelembe kell vennie az egymást követő mérkőzéseket. Más szavakkal, ha eltávolít egy sort egyezés után, amely szintén egyezik, akkor valószínűleg ezt is el kell távolítania.

Elég egyszerűen megvalósul – de egy kicsit utána kell nézni .

printf %s\\n 0 match 2 match match \ 5 6 match match match \ 10 11 12 match 14 15 | sed -ne"x;/match/!{g;//!p;}" 

 0 6 11 12 15  

Úgy működik, hogy minden beolvasott sorra kicseréli a tartási és mintázati tereket – így az utolsó sor minden alkalommal összehasonlítható az aktuális sorral. Tehát amikor sed egy sort olvas, akkor kicseréli puffereinek tartalmát – és az előző sor ekkor a szerkesztő pufferének a tartalma, míg az aktuális sor tartási helyre kerül.

Tehát sed ellenőrzi, hogy az előző sor megfelel-e match , és ha ! nem található meg a két kifejezés a { függvény } futtatásakor. sed g megtartja a tartási teret a mintaterület felülírásával – ami azt jelenti, hogy az aktuális sor ekkor mind a hold, mind a mintaterekben van majd // ellenőrzi, hogy egyezik-e a legutóbb összeállított reguláris kifejezéssel – match -, és ha it nem match van, akkor p be van nyomtatva.

Ez azt jelenti, hogy egy sort csak akkor nyomtatnak ki, ha nem match és a közvetlenül előző sor nem match . Ezenkívül eltekint a match es szekvenciák felesleges cseréjétől.

Ha olyan verziót szeretne, amely tetszőleges számú sort dobhat le match után fordul elő, kicsit több munkára lenne szükség:

printf %s\\n 1 2 3 4 match \ match match 8 \ 9 10 11 12 13 \ 14 match match \ 17 18 19 20 21 | sed -net -e"/match/{h;n;//h;//!H;G;s/\n/&/5;D;}" -ep 

. ..cserélje le az 5-öt az eltávolítani kívánt sorok számával (beleértve az egyező sort) .


1 2 3 4 12 13 14 21 

Vélemény, hozzászólás?

Az email címet nem tesszük közzé. A kötelező mezőket * karakterrel jelöltük