Käytän tätä
cat foo.txt | sed "/bar/d"
poistaa riviä, joka sisältää merkkijonon bar
tiedostossa.
Haluan kuitenkin poistaa nämä rivit ja rivi suoraan sen jälkeen . Mieluiten sed
, awk
tai muussa työkalussa, joka on käytettävissä MinGW32: ssa.
Se on eräänlainen käänteinen siitä, mitä voin saada grep
kanssa -A
ja -B
, jotta voin tulostaa myös vastaavat rivit rivinä ennen / jälkeen vastaavan rivin.
Onko olemassa helppo tapa saavuttaa se?
Kommentit
- Vain tiedot: I ’ m analysoin lokeja, joissa merkinnät ovat kaksirivisiä. Joten haluan löytää merkinnän vastaavan merkinnän ja poistaa sen sekä seuraavan rivin. Siksi minun ei ’ tarvitse käsitellä peräkkäisiä ottelulinjoja, mutta kiitos vastausten täydellisyydestä!
Vastaa
Jos sinulla on GNU sed (joten sulautettu Linux tai Cygwin):
sed "/bar/,+1 d"
Jos bar
kahdella peräkkäisellä rivillä, tämä poistaa toisen rivin analysoimatta sitä. Esimerkiksi, jos sinulla on 3-rivinen tiedosto bar
/ bar
/ foo
, foo
-rivi pysyy.
Kommentit
- +1 pituudelle 🙂 esimerkki Minulla ’ ei ole peräkkäisiä
bar
s, joten tämä on erittäin helppo muistaa. -
sed '/bar/d'
jos haluat vain ” poistaa tietyn merkkijonon sisältävän rivin ” ja ei seuraava. - Jos haluan poistaa kaikki rivit matematiikan jälkeen?
- @Pandya Se on ’ erilainen. Voit käyttää esim.
sed '/math/q'
- @ A.K. Jos haluat vain poistaa vastaavan rivin, se ’ on vielä yksinkertaisempi:
sed '/bar/d'
Vastaus
Jos bar
saattaa esiintyä peräkkäisillä riveillä, voit tehdä seuraavaa:
awk "/bar/{n=2}; n {n--; next}; 1" < infile > outfile
joka voidaan mukauttaa poistamaan enemmän kuin 2 riviä muuttamalla 2 yllä olevalla rivillä poistettavien rivien määrällä, mukaan lukien vastaava.
Jos ei, se ”s helppo tehdä sed
ratkaisulla @MichaelRollins” tai:
sed "/bar/,/^/d" < infile > outfile
Kommentit
- AWK-ratkaisun toinen plus on, että voin korvata
/bar/
/bar|baz|whatever/
. Kohdassased
tämä syntaksi ei näytä toimivan. Id id ”” 13eec19014 ”>
ei näytä toimivan.
sed
käyttämään ” laajennettu ” säännölliset lausekkeet. Lisätietoja täältä: gnu.org/software/sed/manual/html_node/… . Huomaa, että tämä koskee myös grep
. Tässä ’ s oma toimiva esimerkkini: echo $'0a\n1b\n2c' | sed '/0a\|1b/d'
. Vastaa
En puhu sujuvasti sedia, mutta se on helppo tehdä awk:
awk "/bar/{getline;next} 1" foo.txt
awk-komentosarja lukee: riville, joka sisältää palkin, hanki seuraava rivi (getline) ja ohita sitten kaikki seuraava käsittely (seuraava). Lopussa oleva 1 kuvio tulostaa loput rivit.
Päivitä
Kuten kommentissa todettiin, yllä oleva ratkaisu ei toiminut peräkkäisten bar
. Tässä on uudistettu ratkaisu, joka ottaa sen huomioon:
awk "/bar/ {while (/bar/ && getline>0) ; next} 1" foo.txt
Jatkamme nyt lukemista ohittaaksesi kaikki / bar / rivit.
Kommentit
- Jos haluat toistaa
grep -A
100%, sinun on myös käsiteltävä mitä tahansa määrää peräkkäisiäbar
rivit oikein (poistamalla koko lohko ja yksi rivi sen jälkeen).
Vastaa
Tämän saavuttamiseksi sinun on käytettävä sedin komentosarjaominaisuuksia.
$ sed -e "/bar/ { $!N d }" sample1.txt
Esimerkkitiedot:
$ cat sample1.txt foo bar biz baz buz
Komento ”N” liittää seuraavan syöttörivin kuviotilaan. Tämä yhdistettynä mallivastauksen / / bar /) riviin on rivit, jotka haluat poistaa. Voit sitten poista normaalisti komennolla ”d”.
Kommentit
- Kuinka kirjoitan uuden rivin konsoliin? Tai tämä on vain komentosarja?
- @ jakub.g: GNU: n kanssa sed:
sed -e '/bar/{N;d}' sample1.txt
Vastaus
Jos jokin välittömästi ottelun jälkeen oleva rivi on poistettava, sed
-ohjelman on otettava huomioon peräkkäiset ottelut. Toisin sanoen, jos poistat rivin myös vastaavan ottelun jälkeen, luultavasti sinun pitäisi poistaa myös sitä seuraava rivi.
Se toteutetaan yksinkertaisesti – mutta sinun on katsottava hieman taaksepäin .
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
Se toimii vaihtamalla pito- ja kuviotilat jokaiselle luetulle riville – joten viimeistä riviä voidaan verrata joka kertaan nykyiseen. Joten kun sed
lukee rivin, se vaihtaa puskuriensa sisällön – ja edellinen rivi on sen muokkauspuskurin sisältö, kun taas nykyinen rivi asetetaan pitotilaan.
Joten sed
tarkistaa edellisen rivin vastaavuuden match
ja jos sen !
ei löytänyt kahta lauseketta funktiossa {
}
suoritetaan. sed
g
et pitää pitotilan korvaamalla kuviotilan – mikä tarkoittaa, että nykyinen viiva on tällöin sekä pidossa että kuvioissa – ja sitten //
tarkistaa sen vastaavuuden viimeksi koottuun säännölliseen lausekkeeseensa – match
– ja jos se ei match
, se on p
rinted.
Tämä tarkoittaa, että rivi tulostetaan vain, jos se ei match
ja välittömästi edellinen rivi ei match
. Se myös hylkää kaikki tarpeettomat vaihdot match
es -sekvensseille.
Jos haluat version, joka voi pudottaa mielivaltaisen määrän rivejä match
: n jälkeen se tarvitsee hieman enemmän työtä:
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
. ..korvaa 5 rivien lukumäärällä (mukaan lukien vastaava viiva) , jonka haluat poistaa …
1 2 3 4 12 13 14 21