Kuinka leikata johtava ja perään jätettävä välilyönti jokaisen tuotoksen jokaisesta rivistä?

Haluan poistaa kaikki etu- ja loppuosan välilehdet ja välilehdet jokaisen lähdön riviltä.

Onko olemassa yksinkertaista työkalua, kuten trim Voisin lähettää tuotokseni?

Esimerkkitiedosto:

test space at back test space at front TAB at end TAB at front sequence of some space in the middle some empty lines with differing TABS and spaces: test space at both ends 

kommentit

  • Kaikille, jotka etsivät täällä ratkaisua uusien rivien poistamiseen, se on erilainen ongelma. Määritelmän mukaan uusi rivi luo uuden tekstirivin. Siksi tekstirivi ei voi sisältää uutta riviä. Kysymys on uuden rivin poistaminen merkkijonon alusta tai lopusta: stackoverflow.com/questions/369758 tai tyhjän poistaminen rivit tai rivit, jotka ovat vain tyhjää tilaa: serverfault.com/questions/252921

Vastaa

awk "{$1=$1;print}" 

tai lyhyempi:

awk "{$1=$1};1" 

Leikkaa johto ja välilyönti- tai sarkainmerkkien jälkeen 1 ja myös purista sarkaimia ja välilyönnit yhdeksi tilaksi.

Tämä toimii, koska kun määrität jotain jollekin kentistä , awk rakentaa koko tietueen uudelleen. (painettu print) yhdistämällä kaikki kentät ($1, …, $NF) ja OFS (oletusarvoisesti välilyönti).

1 (ja mahdollisesti muu tyhjä merkki s riippuen kielestä ja awk -toteutuksesta)

Kommentit

  • Puolipiste päällä toinen esimerkki on tarpeeton. Voisi käyttää: awk '{$1=$1}1'
  • @Brian, ei, ; vaaditaan tavallisessa awk-syntaksissa
  • Mielenkiintoista … gawk, mawk ja OS X eivät tue puolipistettä ’ s awk. (Ainakin versioilleni (1.2, 4.1.1 ja 20070501)
  • Ainoa asia, mistä ’ pidän tässä lähestymistavassa, on, että menettää toistuvia välilyöntejä rivillä. Esimerkiksi echo -e 'foo \t bar' | awk '{$1=$1};1'
  • echo ' hello ' | xargs

vastaus

Komento voidaan tiivistää samalla tavalla, jos käytät GNU: ta sed:

$ sed "s/^[ \t]*//;s/[ \t]*$//" < file 

Esimerkki

Tässä yllä oleva komento toiminnassa.

$ echo -e " \t blahblah \t " | sed "s/^[ \t]*//;s/[ \t]*$//" blahblah 

Voit käyttää hexdump -näppäintä vahvistaaksesi, että komento sed poistaa haluamasi merkit oikein.

$ echo -e " \t blahblah \t " | sed "s/^[ \t]*//;s/[ \t]*$//" | hexdump -C 00000000 62 6c 61 68 62 6c 61 68 0a |blahblah.| 00000009 

Merkkiluokat

Voit myös käyttää merkkiluokkien nimiä sen sijaan, että luettaisit kirjaimellisesti tällaiset joukot, [ \t]: / p>

$ sed "s/^[[:blank:]]*//;s/[[:blank:]]*$//" < file 

Esimerkki

$ echo -e " \t blahblah \t " | sed "s/^[[:blank:]]*//;s/[[:blank:]]*$//" 

Suurin osa GNU-työkaluista, jotka käyttävät säännöllistä ssions (regex) tukee näitä luokkia (tässä vastaavilla tavallisella ASCII-pohjaisen järjestelmän C-kielellä (ja vain siellä)).

 [[:alnum:]] - [A-Za-z0-9] Alphanumeric characters [[:alpha:]] - [A-Za-z] Alphabetic characters [[:blank:]] - [ \t] Space or tab characters only [[:cntrl:]] - [\x00-\x1F\x7F] Control characters [[:digit:]] - [0-9] Numeric characters [[:graph:]] - [!-~] Printable and visible characters [[:lower:]] - [a-z] Lower-case alphabetic characters [[:print:]] - [ -~] Printable (non-Control) characters [[:punct:]] - [!-/:-@[-`{-~] Punctuation characters [[:space:]] - [ \t\v\f\n\r] All whitespace chars [[:upper:]] - [A-Z] Upper-case alphabetic characters [[:xdigit:]] - [0-9a-fA-F] Hexadecimal digit characters 

Käyttämällä nämä kirjaimellisten joukkojen sijasta näyttävät aina tilan tuhlaukselta, mutta jos olet huolissasi siitä, että koodisi on kannettava tai sinun on käsiteltävä vaihtoehtoisia merkistöjä (ajattele kansainvälistä), haluat todennäköisesti käyttää luokan nimiä .

Viitteet

Kommentit

  • Huomaa, että [[:space:]] ei vastaa [ \t] yleinen tapaus (unicode jne.). [[:space:]] tulee todennäköisesti olemaan paljon hitaampi (koska unicode-tunnissa on paljon enemmän tyhjätiloja kuin vain ' ' ja '\t'). Sama asia kaikille muille.
  • sed 's/^[ \t]*//' ei ole kannettava. Käytännössä POSIX vaatii jopa, että poistamalla välilyönti, taaksepäin viiva tai t merkkiä ja että ’ s mitä GNU sed toimii myös, kun POSIXLY_CORRECT on ympäristössä.
  • Entä jos haluan leikata rivinvaihtomerkkejä? ’ \ n \ n teksti \ n \ n ’
  • Pidän sed-ratkaisusta, koska muut sivuvaikutukset kuten awk-ratkaisussa. Ensimmäinen muunnelma ei toimi, kun kokeilin sitä bashissa OSX jsutilla nyt, mutta merkkiluokan versio toimii: sed 's/^[[:blank:]]*//;s/[[:blank:]]*$//'
  • @EugeneBiryukov katso kommenttini alkuperäinen viesti

Vastaa

xargs ilman argumentteja tekevät sen.

Esimerkki:

trimmed_string=$(echo "no_trimmed_string" | xargs) 

kommentit

  • Tämä supistaa myös useita välilyöntejä rivi, jota ei kysytty kysymyksessä
  • @roaima – totta, mutta hyväksytty vastaus puristaa myös välilyöntejä (mitä kysymyksessä ei vaadittu). Mielestäni todellinen ongelma on tässä, että xargs ei onnistu toimittamaan, jos syötteessä on taaksepäin viivoja ja yksittäisiä lainausmerkkejä.
  • @don_crissti joka ei ’ ei tarkoita sitä, että hyväksytty vastaus vastaa kuitenkin kysymykseen oikein. Mutta tässä tapauksessa tässä sitä ei ’ t merkitty varoitukseksi, kun taas hyväksytyssä vastauksessa se oli. Olen ’ korostanut toivottavasti asiaa, jos se ’ on merkityksellistä tulevalle lukijalle.
  • Se myös taukoja yksittäisissä lainauksissa, kaksoislainauksissa, vinoviivalla. Se suorittaa myös yhden tai useamman echo -kutsu. Jotkut kaiun toteutukset käsittelevät myös vaihtoehtoja ja / tai taaksepäin viivoja … Se toimii myös vain yksirivisellä syötöllä.

Vastaa

Kuten Stéphane Chazelas ehdotti hyväksytyssä vastauksessa, voit nyt
luoda komentosarjan /usr/local/bin/trim:

#!/bin/bash awk "{$1=$1};1" 

ja anna tiedostolle suoritettavat oikeudet:

chmod +x /usr/local/bin/trim 

Nyt voit siirtää kaikki lähdöt esimerkiksi trim:

cat file | trim 

(alla oleviin kommentteihin: käytin tätä aiemmin: while read i; do echo "$i"; done
joka toimii myös hyvin, mutta on vähemmän suorituskykyinen)

Kommentit

  • Onnea, jos tiedosto on valtava ja / tai sisältää vinoviivoja.
  • @don_crissti: Voisitteko kommentoida hieman enemmän ?, mikä ratkaisu olisi sovi paremmin valtaviin tiedostoihin, ja miten voin muokata ratkaisua, jos tiedosto sisältää vinoviivoja?
  • ’ Sinun on käytettävä while read -r line -viivaa vinoviivojen ja säilyttämiseksi silloinkin … . Mitä tulee valtaviin tiedostoihin / nopeuteen, valitsit pahin ratkaisu. En ’ usko, että ’ ei ole mitään pahempaa siellä. Katso vastaukset sivulta Miksi komentosarjan käyttö käsittelee huonoja käytäntöjä? mukaan lukien kommenttini viimeiseen vastaukseen, johon lisäsin linkin nopeuden vertailuarvoon. Täällä olevat sed vastaukset ovat IMO: ssa erittäin hyviä ja paljon parempia kuin read.
  • Voit myös lisätä aliaksen / etc / profile (tai ~ / .bashrc tai ~ / .zshrc jne …) alias trim = ” awk ’ { \ $ 1 = \ $ 1}; 1 ’ ”
  • Ei tarvetta bash, voit tehdä siitä #! /usr/bin/awk -f {$1=$1};1. (varo kuitenkin = -merkkejä sisältäviä tiedostojen nimiä)

Vastaa

Jos tallennat rivejä muuttujina, voit käyttää työtä bash-toiminnolla:

poista johtava välilyönti merkkijonosta:

shopt -s extglob echo ${text##+([[:space:]])} 

poista merkkijonosta jäljellä oleva välilyönti:

shopt -s extglob echo ${text%%+([[:space:]])} 

poista kaikki välilyönnit merkkijonosta:

echo ${text//[[:space:]]} 

Kommentit

  • Kaikkien välilyöntien poistaminen merkkijonosta ei ole sama kuin sekä etu- että lopputilojen poistaminen (kuten kysymyksessä).
  • Paras ratkaisu – se vaatii vain rakennettuja rakenteita eikä ulkoisia prosessihaarukoita.
  • Mukavaa. Komentosarjat suorittavat PALJON nopeammin, jos niiden ’ ei tarvitse hakea ulkopuolisia ohjelmia (kuten awk tai sed). Tämä toimii myös ” moderneilla ” (93u +) ksh-versioilla.

Vastaa

sed -e "s/^[[:space:]]*//" -e "s/[[:space:]]*$//" 

Jos luet riviä uudelleen shell-muuttujaksi, read tekee sen jo , ellei toisin ohjeisteta .

Kommentit

  • +1 merkinnälle read. Joten jos kirjoitat lukemisen aikana, se toimii: cat file | while read i; do echo $i; done
  • @rubo paitsi että esimerkissä kuori käsittelee myös noteeraamattoman muuttujan. Käytä echo "$i" nähdäksesi read

vastaus

Poistaaksesi kaikki etu- ja perätilat tietyltä riviltä ”piped” -työkalun avulla, voin tunnistaa 3 erilaista tapoja, jotka eivät ole täysin samanarvoisia. Nämä erot koskevat syöttörivin sanojen välisiä välejä riippuen odotetusta b: stä ehaviour, teet valintasi.

Esimerkkejä

Selittäkää erot tarkastelemalla tätä nuken syöttöriviä:

" \t A \tB\tC \t " 

tr

$ echo -e " \t A \tB\tC \t " | tr -d "[:blank:]" ABC 

tr on todella yksinkertainen komento. Tällöin se poistaa välilyönnit tai taulukkomerkit.

awk

$ echo -e " \t A \tB\tC \t " | awk "{$1=$1};1" A B C 

awk poistaa etu- ja hännätilat ja puristaa yhdeksi välilyönniksi jokaisen sanojen välisen välilyönnin.

sed

$ echo -e " \t A \tB\tC \t " | sed "s/^[ \t]*//;s/[ \t]*$//" A B C 

Tässä tapauksessa sed poistaa etu- ja pyrstötilat koskematta sanojen väliin.

Huomautus:

Jos kyseessä on yksi sana riviä kohden, tr tekee työn.

Kommentit

  • Kukaan tästä ei kuitenkaan leikkaa viimeisimpiä / johtavia uusia rivejä
  • +1 luettelolle ratkaisuista (joskus odottamattomilla) tuotoksilla.
  • @ user61382 tämä on melko myöhäistä, mutta katso kommenttini alkuperäisestä viestistä.
  • @highmaintenance: käytä komentoa [:space:] kuin [: blank:]. div id = ”dd2bc4a516”>

, kuten:... | tr -d [:space:], myös uusien rivien poistamiseksi. (katso:man tr)

Vastaa

sed on loistava työkalu siihen:

 # substitute ("s/") sed "s/^[[:blank:]]*//; # parts of lines that start ("^") with a space/tab s/[[:blank:]]*$//" # or end ("$") with a space/tab # with nothing (/) 

Voit käyttää sitä tapauksessasi joko tekstin syöttämiseen, esim.

<file sed -e "s/^[[... 

tai toimimalla sen mukaan ”inline”, jos sed on GNU:

sed -i "s/..." file 

mutta lähteen vaihtaminen tällä tavalla on ”vaarallista”, koska sitä ei ehkä voida palauttaa, kun se ei toimi oikein (tai edes silloin, kun se toimii!), Joten varmuuskopioi ensin (tai käytä -i.bak, jonka etuna on myös kannettavuus joillekin BSD: lle sed s)!

Vastaa

Vastaus, jonka ymmärrät yhdellä silmäyksellä:

#!/usr/bin/env python3 import sys for line in sys.stdin: print(line.strip()) 

Bonus: korvaa str.strip([chars]) mielivaltaisilla merkeillä leikata tai käyttää .lstrip() tai .rstrip() tarpeen mukaan.

Kuten rubo77 ”sa nswer , tallenna skriptinä /usr/local/bin/trim ja anna käyttöoikeudet mallilla chmod +x.

vastaus

Jos merkkijono, jota yritetään leikata, on lyhyt ja jatkuva / vierekkäinen, voidaan yksinkertaisesti välittää se parametrina mihin tahansa bash-funktioon:

 trim(){ echo $@ } a=" some random string " echo ">>`trim $a`<<" Output >>some random string<< 

Answer

Kirjoitin tämän kuoritoiminnon käyttämällä awk

awkcliptor(){ awk -e "BEGIN{ RS="^$" } {gsub(/^[\n\t ]*|[\n\t ]*$/,"");print ;exit}" "$1" ; } 

BEGIN{ RS="^$" }:
alussa ennen jäsentämisen aloittamista määritä tietue
erotin olemattomaksi ts. käsittele koko syötettä
yhtenä tietueena

gsub(this,that):
korvaa tämä regexp tällä merkkijonolla

/^[\n\t ]*|[\n\t ]*$/: kyseisen merkkijonon sivu saa kiinni uuden rivin edellisen välilyönnin ja välilehden luokan
tai lähettää uuden rivin välilyönnin ja välilehden luokan ja korvaa ne
tyhjällä merkkijonolla

print;exit: tulosta sitten ja poistu

"$1":
ja välitä funktion ensimmäinen argumentti olla prosessissa awk: lla

miten käyttää:
kopioi koodi yllä, liitä kuoreen ja kirjoita sitten
määrittele funktio.
voit käyttää awkcliptoria komentona ensimmäisen argumentin syöttötiedostona.

esimerkkikäyttö:

echo " ggggg " > a_file awkcliptor a_file 

lähtö:

ggggg 

tai

echo -e "\n ggggg \n\n "|awkcliptor 

lähtö:

ggggg 

Kommentit

  • Voitteko selittää eron vain awk '{$1=$1};1'?

Vastaa

Niille meistä, joilla ei ole tarpeeksi tilaa aivoissa muistaa hämärä sed -syntaksi, käännä vain merkkijono , leikkaa 1. kenttä välilyönnillä ja käännä se takaisin.

cat file | rev | cut -d" " -f1 | rev 

Kommentit

  • Tämä toimii vain, jos kutakin riviä johtaa vain yksi välilyönti ja missään rivissä on enintään yksi sana.

Vastaa

trimpy () { python3 -c "import sys for line in sys.stdin: print(line.strip())" } trimsed () { gsed -e "s/^[[:space:]]*//" -e "s/[[:space:]]*$//" } trimzsh () { local out="$(</dev/stdin)" [[ "$out" =~ "^\s*(.*\S)\s*$" ]] && out="$match[1]" || out="" print -nr -- "$out" } # example usage echo " hi " | trimpy 

Bonus: Korvaa str.strip([chars]) mielivaltaisilla merkeillä leikata tai käyttää tai .rstrip() tarpeen mukaan.

Vastaa

käännöskomento toimisi

cat file | tr -d [:blank:] 

Kommentit

  • Tämä komento ei ole oikea, koska se poistaa kaikki> välilyönnit tiedostosta, ei pelkästään välilyönnin edessä / lopussa.
  • @BrianRedbeard Olet oikeassa. Tämä on edelleen hyödyllinen vastaus monoliittiselle merkkijonolle ilman välilyöntejä.

vastaus

bash-esimerkille:

alias trim="awk "{\$1=\$1};1"" 

käyttö:

echo -e " hello\t\tkitty " | trim | hexdump -C 

tulos:

00000000 68 65 6c 6c 6f 20 6b 69 74 74 79 0a |hello kitty.| 0000000c 

Kommentit

  • awk '{$1=$1};1' vastaus annettiin kauan sitten. Ajatus tehdä siitä aliakseksi ehdotettiin kommentissa melkein yhtä kauan sitten. Kyllä, sinulla on oikeus ottaa jonkun toisen kommentti ja muuttaa se vastaukseksi. Mutta jos teet niin, sinun tulee antaa kunnia ihmisille, jotka julkaisivat idean ennen sinua. Ja tämä on niin triviaali jatko hyväksytylle vastaukselle, että se ei todellakaan ole vaivannäön arvoinen.
  • Ajatuksena oli tehdä alias. En ole ’ nähnyt vastausta aiemmin.
  • ja toinen asia pinosta: ” Kiitos palautteesta! Alle 15 maineen saaneiden äänet kirjataan, mutta eivät muuta julkisesti näytettävää viestiä. ”

Vastaa

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