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
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'
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/
. Ased
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 agrep
fájlra is érvényes. Itt ' s a saját működő példám:echo $'0a\n1b\n2c' | sed '/0a\|1b/d'
.
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).
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
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