jäsennän postilaatikkotiedoston, joka tallentaa sähköpostipalvelinraportit epäonnistuneesta sähköpostista. Haluan purkaa virheelliset sähköpostiosoitteet, joten että poistan ne järjestelmästä. Lokitiedosto näyttää tältä:

...some content... The mail system <[email protected]>: host mx1.hotmail.com[65.54.188.94] said: 550 Requested action not taken: mailbox unavailable (in reply to RCPT TO command) ...some content... The mail system <[email protected]>: host viking.optimumpro.net[79.101.51.82] said: 550 Unknown user (in reply to RCPT TO command) ...some content... The mail system <[email protected]>: host mta5.am0.yahoodns.net[74.6.140.64] said: 554 delivery error: dd This user doesn"t have a yahoo.com account ([email protected]) [0] - mta1172.mail.sk1.yahoo.com (in reply to end of DATA command) ...etc. 

Sähköpostiosoitteeseen tulee kaksi riviä ”Postijärjestelmä” -rivin jälkeen. Tällaisen grepin käyttäminen antaa minulle ”Postijärjestelmä” -rivin ja seuraavat kaksi riviä:

grep -A 2 "The mail system" mbox_file 

En kuitenkaan tiedä miten poistaa ”Postijärjestelmä” -rivi ja toinen tyhjä rivi tästä lähdöstä. Luulen voivani kirjoittaa PHP / Perl / Python-komentosarjan tekemään sen, mutta ihmettelen, onko tämä mahdollista grepillä tai muulla tavallisella työkalulla. Yritin antaa negatiivisen siirtymän parametrille -B:

grep -A 2 -B -2 "The mail system" mbox_file 

Mutta grep valittaa:

grep: -2: invalid context length argument 

Onko olemassa tapa tehdä tämä grepillä?

Kommentit

  • -B hyväksyy numeron kuten -A, ja se näyttäisi edelliset rivit ennen ottelua.
  • Kyllä, se on totta, mutta Milano ei ole ' kiinnostunut ottelua edeltävistä asioista. Hänen kohtaamansa ongelma on, että -A ja -B hyväksyvät vain positiiviset arvot … ja että joka tapauksessa -A ja -B ei voida käyttää ' t suhteessa toisiinsa , kuten hän on yrittänyt tehdä.
  • Hum, vain varmistaakseni: nämä ovat nuken osoitteita, joita et (suoraan) poinut saamastasi tiedostosta, eikö?
  • @Matthieu M. ei, ne ovat todellisesta lokitiedostosta. Ajattelin, että ne ovat joka tapauksessa virheellisiä osoitteita, mikä ' on järkevää keksiä nuken osoitteet, jotka saattavat olla kelvollisia.
  • stackoverflow.com/questions/8101701/…

vastaus

Yksinkertaisin tapa ratkaista se käyttämällä vain grep on putkia vielä yksi käänteinen grep loppuun . Esimerkiksi:

grep -A 4 "The mail system" temp.txt | grep -v "The mail system" | grep -v "^\d*$" 

Vastaa

Jos et ole lukittu käyttämällä grep, yritä sed

sed -n "/The mail system/{n;n;p}" 

Kun se löytää ”Postijärjestelmän” sisältävän rivin, lukee seuraavan rivin kahdesti n;n; kautta ja hylkää kaikki edelliset rivit samalla tavalla.
Tämä jättää kolmannen rivin ryhmäsi kuviotilaan, joka sitten tulostetaan sed ”s p -komennolla. Edellinen vaihtoehto -n estää kaiken muun tulostuksen .

Jos haluat tulostaa myös seuraavat kaksi riviä, kyseessä on vain seuraava ja tulosta n;p vielä kaksi kertaa.

sed -n "/The mail system/{n; n;p; n;p; n;p}" 

Seuraava rivi haluamillesi riveille voidaan kerätä ja tulostaa vain yksi lohko vain yhdellä pN lukee seuraavan rivin ja liittää sen kuviotilaan.

Tässä on viimeinen tiivistetty versio …

sed -n "/The mail system/{n;n;N;N;p}" 

Jos haluat ryhmäerotin , joka on samanlainen kuin grep wouuld -tulos, voit käyttää sed ”s insert -komentoa i (jonka on oltava rivin viimeinen komento) …

Tässä on syntaksin sisällyttää ryhmänerotin

sed -n "/The mail system/{n;n;N;N;p;i-- }" > output-file # or | ... 

Tässä on ensimmäisen ottelun tulos:

<[email protected]>: host mx1.hotmail.com[65.54.188.94] said: 550 Requested action not taken: mailbox unavailable (in reply to RCPT TO command) -- 

Kommentit

  • +1. Kiitos. En tarvitse ' sitä tässä tapauksessa, mutta en ' pidän tämän kirjanmerkin, jos saan monimutkaisempia asioita käsitellä.
  • Tämä on hieno vastaus!

Vastaa

grep -A 2 -B -2 "The mail system" mbox_file 

-B on tarkoitettu edellisille riveille, joten -negatiivista arvoa ei tarvitse antaa.

grep -A 2 -B 2 "The mail system" mbox_file # This will work please check 

Kommentit

  • Tämä ei vastaa kysymykseen. -A 2 -B 2 tulostaa kahdelta riviltä kontekstin edestä kahdelle riville kontekstin jälkeen. Kysymys on tulostamisesta 2 riviltä kontekstin jälkeen 4 riville kontekstin jälkeen.

Vastaus

I ei ole mitään syytä käyttää vain grep-tiedostoja, paitsi jos tämä on tiukka rajoitus. Sitä ei voida tehdä yhdellä grep-kutsulla.

grep -A 2 "The mail system" mbox_file | tail -n +3 
  • grep: Etsi rivi ja tulosta 2 riviä jälkeen,
  • häntä: leikkaa kaksi ensimmäistä riviä (ts. aloita kolmannelta riviltä).

Kommentit

  • Tämä toimii vain, jos on olemassa yksi vastaava rivi, mikä ei todennäköisesti ole kysymys.
  • Kysymys ei ole mikään, mutta se auttaa minua nykyisessä tilanteessani :-).
  • @ daniel.neumann tiedän, mutta olin täsmälleen kengissäsi ja ajattelin muiden ' Google-fu johtaa myös täällä.

Vastaa

Jos haluat poistaa kaksi ensimmäistä riviä, vie se kohtaan sed

sed "1,2d" 

kuten kohdassa

 grep -A 2 "The mail system" mbox_file | sed "1,2d"  

Kommentit

  • Olet unohtanut, että kuvio esiintyy monta kertaa. Jos “Sähköpostijärjestelmä” näkyy riveillä 4, 14, 24, 34,…, OP haluaa nähdä rivit 6, 16, 26, 36, … Vastauksesi antaa 6, 14-16, 24-26, 34- 36,….

Vastaa

Tämä tulostaa yhden seuraavan rivin regexp-vastaavuuden jälkeen käyttäen Perl

perl -ne "print if( (/The mail system/ && ($end=1))..!$end-- )" 

Vastaa

Sähköpostiosoitettasi ei julkaista. Pakolliset kentät on merkitty *