Haluan poistaa txt-tiedoston viimeisen sarakkeen, enkä tiedä, mikä sarakkeen numero On. Kuinka voin tehdä tämän?
Esimerkki:
Syöttö:
1223 1234 1323 ... 2222 123 1233 1234 1233 ... 3444 125 0000 5553 3455 ... 2334 222
Ja haluan, että lähtöni on :
1223 1234 1323 ... 2222 1233 1234 1233 ... 3444 0000 5553 3455 ... 2334
Kommentit
Vastaa
Kanssa awk
:
awk "NF{NF-=1};1" <in >out
tai:
awk "NF{NF--};1" <in >out
tai:
awk "NF{--NF};1" <in >out
Vaikka tämä näyttää olevan voodoo, se toimii. Jokaisessa näistä awk-komennoista on kolme osaa.
Ensimmäinen on NF
, mikä on toisen osan ennakkoedellytys. NF
on muuttuja, joka sisältää rivillä olevien kenttien määrän. AWK: ssa asiat ovat totta, jos ne eivät ole 0 tai tyhjät merkkijonot ""
. Siksi toinen osa (jossa NF
vähennetään) tapahtuu vain, jos NF
ei ole 0.
Toinen osa (joko NF-=1
NF--
tai --NF
) vähennetään vain yksi muuttujasta NF
. Tämä estää viimeisen kentän tulostamisen, koska kun muutat kenttää (poistat tässä tapauksessa viimeisen kentän), awk
rakennetaan uudelleen $0
, ketjutetaan kaikki välilyönnillä erotetut kentät oletusarvoisesti . $0
ei enää sisältänyt viimeistä kenttää.
Viimeinen osa on 1
. Se ei ole maaginen, sitä käytetään vain lausekkeena, joka tarkoittaa true
. Jos awk
-lauseke arvioi arvon tosi ilman mitään siihen liittyvää toimintoa, awk
oletustoiminto on print $0
.
Kommentit
- @JJoao: Ai, kiitos, unohdin
--
. Huomautus: Tarvitset tällä hetkellä;1
POSIX-yhteensopivaksi. - Alkuperäinen vaistoni olisi käyttää for for -silmukkaa, mutta tämä on paljon ytimekkäämpi ja älykkäempi.
- On ' syytä huomata, että jos ' käyttää muuta kuin oletusarvoista erotinta, ' täytyy tehdä joitain muutoksia. Olettaen, että
,
on erottimesi:awk -F',' 'BEGIN { OFS = FS }; NF { NF -= 1 }; 1' < in > out
- NF-arvon pienentämisen vaikutus on POSIXin määrittelemätön käyttäytyminen – saat erilainen lähtö riippuen siitä, mitä awkia ' suoritat. Jotkut awk-sovellukset poistavat viimeisen kentän haluamallasi tavalla, jotkut eivät tee mitään ollenkaan, ja toiset voivat ilmoittaa syntaksivirheestä tai mistä tahansa muusta.
Vastaa
grep
: n käyttäminen PCRE: n kanssa:
$ grep -Po ".*(?=\s+[^\s]+$)" file.txt 1223 1234 1323 ... 2222 1233 1234 1233 ... 3444 0000 5553 3455 ... 2334
GNU: n käyttäminen sed
:
$ sed -r "s/(.*)\s+[^\s]+$/\1/" file.txt 1223 1234 1323 ... 2222 1233 1234 1233 ... 3444 0000 5553 3455 ... 2334
kommentit
- @ramin varma. .voisitko kysyä sitä uudeksi kysymykseksi (tällä tavalla tämä sivusto toimii) 🙂
- @ramin Antaako se sinulle mitään aikarajoitus tai varoitus?
- siinä sanotaan, että tämä ei ole normaalia kysymystä!
- @ramin Ok .. ota yhteyttä järjestelmänvalvojaan, ehkä he voivat auttaa sinua siinä. btw tarkasitko vanhaa laadunvarmistusta kysymyksesi suhteen? on mahdollista, että kysymys on jo esitetty ja siihen on vastattu.
- Älä ' t kysy superperuskysymyksiä, kuten " miten voin nimetä tiedostonimen uudelleen Linuxissa ". Käytä Googlea.
Vastaa
Perlin käyttö:
perl -lane "$,=" ";pop(@F);print(@F)" in
Käyttämällä rev
+ cut
:
rev in | cut -d " " -f 2- | rev
vastaus
GNU sed: n käyttö:
sed -r "s/\s+\S+$//" input.txt
Yleisesti ottaen tämä toimii BSD sedin kanssa OSX: ssä sekä GNU sed: n kanssa:
sed "s/[[:space:]]\{1,\}[^[:space:]]\{1,\}$//" input.txt
Vastaa
Jos erotin on aina yksi merkki (joten kaksi tai useampia peräkkäisiä erotimia merkitsee tyhjiä kenttiä), voit head
vain syöttötiedoston ensimmäisen rivin, laskea erotimet ( n
erotin tarkoittaa, että kenttien lukumäärä on n+1
) ja käytä sitten cut
tulostaaksesi 1
st-kenttä n
-kenttään (toiseksi viimeinen), esim. sarkaimilla erotetulla syötteellä:
n=$(head -n 1 infile | tr -dc \\t | tr \\t \\n | wc -l) cut -f1-$n infile > outfile
tai esim. csv -tiedostolla:
n=$(head -n 1 infile | tr -dc , | tr , \\n | wc -l) cut -d, -f1-$n infile > outfile
Suoritan joitain vertailuarvoja myöhemmin, jos minulla on aikaa, mutta mielestäni tämä on valtava panos ratkaisun on oltava nopeampi kuin muut regexiä käyttävät ratkaisut, koska tämä prosessoi vain vähän ensimmäisellä rivillä saadakseen kenttien lukumäärän ja käyttää sitten cut
, joka on optimoitu tälle työlle. / p>
Vastaa
Voit kannettavasti käyttää jompaakumpaa näistä:
sed "s/[[:space:]]*[^[:space:]]*$//" file awk "{sub(/[[:space:]]*[^[:space:]]*$/,"")}1" file
vastaus
vim: n käyttäminen:
Avaa tiedosto vimissä
vim <filename>
Siirry ensimmäiselle riville siltä varalta, että kohdistin on missään muualla.
gg
Luo makro nimeltä ”q” qq
, joka menee nykyisen rivin takaosaan $
ja palaa sitten viimeiseen välilyöntiin F
(iso kirjain F, jota seuraa kirjaimellinen VÄLINÄPPÄIN) ja poista sitten nykyisestä sijainnista rivin loppuun D
siirry seuraavalle riville j
ja lopeta makrojen nauhoitus q
-toiminnolla.
qq$F Djq
Nyt voimme toistaa makromme @q
-merkillä jokaiselle riville.
Voimme myös painaa @@
viimeisen makron toistaminen tai jopa helpompaa:
99@q
makron toistaminen 99 kertaa.
Huomaa: Numero ei saa täsmätä rivien kanssa.
vastaus
Ihmisille, joilla on samanlainen ongelma, mutta joilla on erilaiset kentän erottimet, tämä awk
-menetelmä säilyttää kenttäerottimen oikein:
$ cat file foo.bar.baz baz.bar.foo $ awk -F"." "sub(FS $NF,x)" file foo.bar baz.bar
cut
kuulostaa työn työkalulta.