Alla on tiedoston teksti:

Pseudo name=Apple Code=42B state=fault Pseudo name=Prance Code=43B state=good 

Minun täytyy napata ”42B” ja hanki ulostulo yllä olevasta tekstistä, kuten:

Pseudo name=Apple Code=42B state=fault 

Onko kukaan aavistustakaan tämän saavuttamiseksi käyttämällä grep / awk / sed?

Kommentit

  • Merkitsit tämän kysymyksen vain " grep " -merkillä. Etsitkö sitten vain " grep " -ratkaisuja? Määrität kysymyksessä myös awk & sed. Voimmeko lisätä nuo tunnisteet? En ollut ' varma aikomuksestasi, kun muokkain kysymystä viime yönä.
  • stackoverflow.com/ kysymykset / 12024410 / …

vastaus

Kanssa awk

awk -v RS="" "/42B/" file 

RS= vaihtaa syötetietueen erotinta uudesta rivistä tyhjiin riveihin. Jos jokin tietueen kenttä sisältää /42B/, tulosta tietue.

"" (tyhjä merkkijono) on taika arvo, jota käytetään edustamaan tyhjiä rivejä POSIXin mukaisesti:

Jos RS on tyhjä, sitten tietueet erotetaan sekvensseillä, jotka koostuvat <newline> plus yhdestä tai useammasta tyhjästä rivit, tyhjät rivit, jotka johtavat tai ovat perässä, eivät saa johtaa tyhjiin tietueisiin syötteen alussa tai lopussa, ja <newline> on aina oltava kentän erotin, riippumatta siitä, minkä arvo FS on.

Lähtökappaleita ei erotettava, koska lähdönerotin on yksi uusi rivi. Varmista, että lähtökappaleiden välillä on tyhjä rivi, asettamalla lähtötietueiden erotin kahteen uuteen riviin:

awk -v RS="" -v ORS="\n\n" "/42B/" file 

kommentit

  • +1 tyylikkääseen ratkaisuun. Sinun <

ei kuitenkaan tarvitse ohjata tiedostoa uudelleen …

  • sormet olivat autopilotissa.
  • @jasonwryan, ellet tarvitse pääsyä tiedostolle awk (FILENAME), se ' ei ole huono idea käyttää uudelleenohjausta, koska näin vältetään ongelmat tiedostonimessä = tai alkaa - (tai on -), tekee johdonmukaiset virheilmoitukset ja välttää awk: n suorittamista tai muiden uudelleenohjausten suorittamista, jos syötetiedosto voidaan ' avata.
  • Vastaus

    Olettaen, että tiedot on jäsennelty siten, että ne ovat aina haluamasi rivi ennen ja jälkeen, voit käyttää grep: n -A (jälkeen) ja -B (ennen) kytkimiä kertomaan, että siihen sisällytetään yksi rivi ennen ottelua ja yksi rivi sen jälkeen:

    $ grep -A 1 -B 1 "42B" sample.txt Pseudo name=Apple Code=42B state=fault 

    Jos haluat samoja numerorivejä hakutermin edessä ja jälkeen, voit käyttää -C (konteksti) -kytkintä:

    $ grep -C 1 "42B" sample.txt Pseudo name=Apple Code=42B state=fault 

    Jos haluat olla tiukempi sovitettaessa useita rivejä, voit käyttää työkalua pcregrep vastaamaan kuvio useilla viivoilla:

    $ pcregrep -M "Pseudo.*\n.*42B.*\nstate.*" sample.txt Pseudo name=Apple Code=42B state=fault 

    Yllä oleva kuvio vastaa seuraavasti:

    • -M – useita rivejä
    • "Pseudo.*\n.*42B.*\nstate.*" – vastaa merkkijonoryhmää, jossa ensimmäinen merkkijono alkaa sanalla "Pseudo", jota seuraa mitä tahansa merkkejä rivin loppuun \n, jota seuraa kaikki merkit merkkijonoon "42B", jota seuraa kaikki merkit, kunnes toinen rivin pää (\n), jota seuraa merkkijono "state" ja kaikki merkit.

    Kommentit

    • -C (konteksti) voidaan käyttää pikakuvakkeena, jos -A ja -B ovat samat.
    • @DavidBaggerman – kiitos. Lisättiin se vastaukseen.
    • Miksi yksi alas -äänestys? Tämä vastaa kysymykseen.

    vastaus

    grep joillakin Unixin makuilla on -p -merkki kappaleelle. Tiedän, että AIX tekee .

    grep -p 42B <myfile> 

    tekisi juuri sen, mitä sinä siellä pyydät YMMV: llä ja GNU: n grepillä ei ole tätä lippua.

    Kommentit

    • P-lipun käyttäminen olisi ihanaa. Varsinkin jos sitä käytetään yhdessä -v: n kanssa, jotta voit sulkea kokonaiset kappaleet ulos tuotoksesta.

    Vastaus

    On todennäköisesti samalla tavoin helppo tapa tehdä se awk: llä, mutta perl:

    cat file | perl -ne "BEGIN { $/="\n\n" }; print if $_ =~ /42B/;" 

    Siinä sanotaan periaatteessa, että tiedosto jaetaan tyhjiksi riveiksi rajatuiksi paloiksi ja tulostetaan sitten vain säännöllisen lausekkeenne vastaavat palat. Kommentit

    • Tätä voidaan yksinkertaistaa käyttämällä vaihtoehtoja ja lyhenteitä ja menettämällä ; perl -00 -ne 'print if /42B/' file

    Vastaa

    Muu perl-ratkaisu, ilman tyhjän rivin lopussa:

    perl -00ne "if ($_ =~ /42B/) {chomp($_); printf "%s\n",$_}" foo 

    esimerkki

    % perl -00ne "if ($_ =~ /42B/) {chomp($_); printf "%s\n",$_}" foo Pseudo name=Apple Code=42B state=fault % cat foo Pseudo name=Apple Code=42B state=fault Pseudo name=Prance Code=43B state=good 

    Kommentit

    • Tai lyhyempi (ja siten helppolukuisempi), kuten triplee kirjoitti kommentissa: perl -00 -ne 'print if /42B/' file.

    Vastaa

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