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ä p
… N
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-- )"