Kuinka shell-komentoa käytetään vain tekstitiedoston ensimmäisen ja viimeisen sarakkeen näyttämiseen?

Tarvitsen apua selvittääkseen, kuinka sed-komennolla voidaan näyttää vain tekstitiedoston ensimmäinen ja viimeinen sarake. Tässä on tähän mennessä sarakkeessa 1:

cat logfile | sed "s/\|/ /"|awk "{print $1}" 

Minun heikko yritys saada viimeinen sarake näyttämään oli myös:

cat logfile | sed "s/\|/ /"|awk "{print $1}{print $8}" 

Tämä kuitenkin vie ensimmäisen ja viimeisen sarakkeen ja yhdistää ne yhteen luetteloon. Onko mahdollista tulostaa ensimmäinen ja viimeiset sarakkeet selkeästi sed- ja awk-komennoilla?

Esimerkkisyöttö:

foo|dog|cat|mouse|lion|ox|tiger|bar 

Kommentit

  • Anna näyte syötteestä.

Vastaa

Melkein siellä. Laita molemmat sarakeviitteet vierekkäin.

cat logfile | sed "s/|/ /" | awk "{print $1, $8}" 

Huomaa myös, että sinun ei tarvitse cat täällä .

sed "s/|/ /" logfile | awk "{print $1, $8}" 

Huomaa myös, että voit sanoa awk, että sarakkeiden erottimet ovat |, tyhjien sijasta, joten et tarvitse myöskään sed.

awk -F "|" "{print $1, $8}" logfile 

-ehdotusten mukaan Caleb , jos haluat ratkaisun, joka tuottaa edelleen viimeisen kentän , vaikka niitä ei olisikaan tarkalleen kahdeksan, voit käyttää $NF.

awk -F "|" "{print $1, $NF}" logfile 

Jos haluat myös | -erottimien säilyttämiseksi, välilyönnin sijasta voit määrittää lähtökentän erottimet. Valitettavasti se on hieman kömpelömpää kuin vain käyttämällä -F -lippua, mutta tässä on kolme lähestymistapaa.

  • Voit määrittää syötteen ja tuloskentän erottimet itse awk -sarakkeessa BEGIN-lohkossa.

    awk "BEGIN {FS = OFS = "|"} {print $1, $8}" logfile 
  • Voit määrittää nämä muuttujat, kun soitat awk komentoriviltä -v -lipun kautta.

    awk -v "FS=|" -v "OFS=|" "{print $1, $8}" logfile 
  • tai yksinkertaisesti:

    awk -F "|" "{print $1 "|" $8}" logfile 

kommentit

  • Hyvää työtä tämän ongelman yksinkertaistamisen selvittämiseksi. Voit lisätä huomautuksen siitä, miten | käytetään lähtöerottimena sijaan oletustila merkkijonon ketjutukseen. Voit myös selittää käyttämään $NF -koodauksen sijaan kovaa koodausta $8 saadaksesi viimeisen sarakkeen.
  • miten tämän jälkeen tiedosto päivitetään?
  • @pankajprasad Kirjoita uuteen tiedostoon wit h > korvaa sitten vanhan tai käytä sponge. Tämä on kuitenkin todella uusi kysymys.
  • @Sparhawk se toimii, mutta sisällön hakeminen poistetaan. miten käsitellä sitä?
  • @pankajprasad Sinun on esitettävä uusi kysymys. Napsauta yläosassa olevaa suurta sinistä painiketta ” Esitä kysymys ”.

Vastaa

Käytät silti awk:

awk "{ print $1, $NF }" file 

Kommentit

  • Eikö ’ t tarvitse määrittää syöttökentän erotin (koska tässä tapauksessa näyttää olevan olla | pikemminkin välilyönti) -F\| tai vastaavan kanssa? Entä jos hän haluaisi käyttää samaa erottinta lähdössä?
  • @Caleb Todennäköisesti: Odotin OP: ta vahvistamaan, miltä tarkalleen tulo näytti, sen sijaan että yritän arvaus ei-toimivien esimerkkien perusteella …
  • Huomaa, että oletetaan, että syötteessä on vähintään 2 kenttää.
  • @St é phaneChazelas OP ilmoitti koodissa selvästi, että sillä on aina kahdeksan kenttää.
  • @ michaelb958 Mielestäni ” selvästi ” yliarvioi tapauksen, vain vähän 🙂

Vastaa

Korvaa vain ensimmäisestä viimeiseen | | (tai välilyönnillä, jos haluat):

sed "s/|.*|/|/" 

Huomaa, että vaikka ei ole sed -toteutusta, jossa | on erityinen (kunhan jatkettu säännöllinen lausekkeita ei ole otettu käyttöön -E tai joissakin toteutuksissa), \| itsessään on erityinen joissakin, kuten GNU sed. Joten sinun ei pidä paeta |, jos aiot sen vastaavan merkkiä |.

Jos korvataan välilyönnillä ja jos syötteessä voi jo olla rivejä, joissa on vain yksi |, sinun on käsiteltävä sitä erityisesti nimellä |.*| ei tiennyt näissä.Se voi olla:

sed "s/|\(.*|\)\{0,1\}/ /" 

(eli tee .*| -osasta valinnainen) Tai:

sed "s/|.*|/ /;s/|/ /" 

tai:

sed "s/\([^|]*\).*|/\1 /" 

Jos haluat ensimmäisen ja kahdeksannen kentän kenttien lukumäärästä riippumatta tulo, niin se on vain:

cut -d"|" -f1,8 

(kaikki ne toimisivat minkä tahansa POSIX-yhteensopivan apuohjelman kanssa olettaen, että tulo on muodostaa kelvollisen tekstin (etenkin sed ei yleensä toimi, jos syötteessä on tavuja tai tavujärjestyksiä, jotka eivät muodosta kelvollisia merkkejä nykyisessä kielialueessa, kuten esimerkiksi printf "unix|St\351phane|Chazelas\n" | sed "s/|.*|/|/" UTF-8-kielialueella)).

Vastaa

Jos löydät itsesi awk- ja sed-less, voit saavuttaa sama asia coreutilsin kanssa:

paste <( cut -d"|" -f1 file) \ <(rev file | cut -d"|" -f1 | rev) 

kommentit

  • cut on puhtaampi ja pienikokoisempi kuin awk / sed, kun olet vain kiinnostunut ensimmäisestä sarakkeesta tai jos viivaimet ovat kiinteät (ts. ei vaihtelevaa määrää välilyöntejä).
  • Melko tyylikäs!

Vastaa

Vaikuttaa siltä, että yrität saada ensimmäisen ja viimeisen tekstikentän, jotka on rajattu |.

Oletin, että lokitiedostosi sisältää alla olevan tekstin,

foo|dog|cat|mouse|lion|ox|tiger|bar bar|dog|cat|mouse|lion|ox|tiger|foo 

Ja haluat tuotos, kuten,

foo bar bar foo 

Jos kyllä, niin tässä tulee komento ”s”

GNU sedin kautta,

sed -r "s~^([^|]*).*\|(.*)$~\1 \2~" file 

Esimerkki:

$ echo "foo|dog|cat|mouse|lion|ox|tiger|bar" | sed -r "s~^([^|]*).*\|(.*)$~\1 \2~" foo bar 

kommentit

  • Sarakkeita ei rajaa putki | mutta ne ovat sarakkeissa, olen kiinnostunut käyttämään sediä, mutta en käyttämään awk-komentoa kuten teit komennossasi: sed -r ’ s ~ ^ ([^ |] *) . * \ | (. *) $ ~ \ 1 \ 2 ~ ’ -tiedosto
  • ” Sarakkeet ovat ei erotettu putkella | mutta ne ovat sarakkeissa ”. Tarkoitatko, että sarakkeet erotetaan välilyönneillä?
  • Otosyöttö ja lähtö olisi parempi.

Vastaa

Sinun pitäisi todennäköisesti tehdä se sed -toiminnolla – tekisin kuitenkin – mutta koska kukaan ei ole vielä kirjoittanut tätä:

while IFS=\| read col1 cols do printf %10s%-s\\n "$col1 |" " ${cols##*|}" done <<\INPUT foo|dog|cat|mouse|lion|ox|tiger|bar INPUT 

OUTPUT

 foo | bar 

Vastaa

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