Hogyan vághatom le a kimenet minden sorából a vezető és a záró szóközt?

Szeretném eltávolítani az összes vezető és záró szóközt és tabulátort a kimenet minden sorából.

Van-e olyan egyszerű eszköz, mint például trim Bemutathatnám a kimenetemet?

Példa fájl:

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 

Megjegyzések

  • Annak, aki itt keres megoldást az új sorok eltávolítására, az más probléma. Definíció szerint egy új sor új szövegrészt hoz létre. Ezért egy szövegsor nem tartalmazhat új sort. A feltenni kívánt kérdés az, hogy hogyan lehet eltávolítani egy új sort a karakterlánc elejéről vagy végéről: stackoverflow.com/questions/369758 , vagy hogyan lehet eltávolítani az üreset csak üres szóközök: serverfault.com/questions/252921

Válasz

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

vagy rövidebb:

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

A vezető és szóköz vagy tabulátor karakterek utolsók 1 és lapok sorozatainak összenyomása és szóközök egyetlen szóközbe.

Ez azért működik, mert amikor valamit hozzárendel a mezőkhöz , awk újjáépíti az egész rekordot. (a print nyomtatásával) az összes mező összekapcsolásával ($1, …, $NF) OFS -vel (alapértelmezett szóköz).

1 (és esetleg más üres karakter s a területi beállításoktól és a awk megvalósítástól függően)

Megjegyzések

  • pontosvessző be a második példa felesleges. Használhatja: awk '{$1=$1}1'
  • @Brian, nem, a ; szükséges a szokásos awk szintaxisban
  • Érdekes … A gawk, a mawk és az OS X ‘ s awk nem támogat pontosvesszőt. (Legalább az én verzióimnál (1.2, 4.1.1, illetve 20070501)
  • Az egyetlen dolog, ami nem tetszik ‘ ebben a megközelítésben, az az, hogy elveszíti az ismétlődő szóközöket a soron belül. Például: echo -e 'foo \t bar' | awk '{$1=$1};1'
  • echo ' hello ' | xargs

Válasz

A parancs tömöríthető, így ha a GNU-t használja sed:

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

Példa

Itt működik a fenti parancs.

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

A hexdump segítségével meggyőződhet arról, hogy az sed parancs helyesen csíkolja le a kívánt karaktereket.

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

Karakterosztályok

Használhat karakterosztályokat is, ahelyett, hogy szó szerint felsorolná az ilyen halmazokat, [ \t]:

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

Példa

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

A legtöbb GNU eszköz, amely a rendszeres expre Az ssions (regex) támogatja ezeket az osztályokat (itt az egyenértékükkel az ASCII alapú rendszer tipikus C területi beállításában (és csak ott)).

 [[: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 

ezek a szó szerinti halmazok helyett mindig helykidobásnak tűnnek, de ha aggódsz a kódod hordozhatósága miatt, vagy alternatív karakterkészletekkel kell foglalkoznod (gondolkodj nemzetközi módon), akkor valószínűleg az osztályneveket akarod használni .

Hivatkozások

Megjegyzések

  • Vegye figyelembe, hogy a [[:space:]] nem egyenértékű a [ \t] általános eset (unicode stb.). A [[:space:]] valószínűleg sokkal lassabb lesz (mivel az unicode-ban sokkal többféle szóköz van, mint csak ' ' és '\t'). Ugyanez a helyzet a többiekkel is.
  • sed 's/^[ \t]*//' nem hordozható. Gyakorlatilag a POSIX még azt is megköveteli, hogy a szóköz, a visszavonás vagy a t karakterek eltávolításához, és hogy ‘ legyen az, amit a GNU akkor is megteszi, ha POSIXLY_CORRECT a környezetben van.
  • Mi van, ha újsoros karaktereket akarok levágni? ‘ \ n \ n szöveg \ n \ n ‘
  • Szeretem a sed megoldást, mivel nincs egyéb mellékhatások, mint az awk megoldásnál. Az első variáció nem működik, amikor most bash-ban kipróbáltam az OSX jsut-on, de a karakterosztály-verzió működik: sed 's/^[[:blank:]]*//;s/[[:blank:]]*$//'
  • @EugeneBiryukov lásd a kommentemet az eredeti bejegyzés

Válasz

Az argumentumok nélküli xargs ezt teszi.

Példa:

trimmed_string=$(echo "no_trimmed_string" | xargs) 

Megjegyzések

  • Ez több helyet is összehúz egy sor, amelyet a kérdésben nem kértek
  • @roaima – igaz, de az elfogadott válasz szóközöket is szorít (amit a kérdés nem kért). Azt hiszem, az igazi probléma itt az, hogy a xargs nem fog teljesülni, ha a bemenet visszavonásokat és egyes idézőjeleket tartalmaz.
  • @don_crissti, amely nem ‘ nem jelenti azt, hogy az elfogadott válasz helyesen válaszolja meg a feltett kérdést. De ebben az esetben itt nem ‘ t jelöltek meg figyelmeztetésként, míg az elfogadott válaszban ez volt. Remélhetőleg kiemeltem a tényt ‘, ha ‘ releváns lesz egy jövőbeli olvasó számára.
  • Ez is törések az egyes idézőjelekben, a dupla idézőjelekben, a visszavágó karakterekben. Egy vagy több echo meghívást is futtat. Néhány visszhang-megvalósítás az opciókat és / vagy a visszavágásokat is feldolgozza … Ez is csak egysoros bevitelnél működik.

Válasz

Ahogy Stéphane Chazelas javasolja az elfogadott válaszban, most
létrehozhat egy szkriptet /usr/local/bin/trim:

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

és adja meg a fájl futtatható jogait:

chmod +x /usr/local/bin/trim 

Most minden kimenetet átadhat például az trim fájlnak:

cat file | trim 

(az alábbi megjegyzésekhez: ezt korábban használtam: while read i; do echo "$i"; done
ami szintén jól működik, de kevésbé teljesít)

Megjegyzések

  • Sok szerencsét, ha a fájlja hatalmas és / vagy visszavágásokat tartalmaz.
  • @don_crissti: tudna még kommentálni egy kicsit ?, melyik megoldás lenne jobban illeszkedik a hatalmas fájlokhoz, és hogyan módosíthatnám a megoldásomat, ha a fájl visszavonást tartalmaz?
  • ‘ Akkor is használnia kell a while read -r line -t a visszavágások és a megőrzéséhez … . Ami a hatalmas fájlokat / sebességet illeti, valóban a legrosszabb megoldást választotta. Nem ‘ nem gondolom, hogy ‘ van valami rosszabb odakinn. Lásd a kérdésre adott válaszokat. Miért használ egy shell ciklust a szöveg rossz gyakorlatának feldolgozására? , beleértve az utolsó válaszhoz fűzött megjegyzésemet is, ahol linket adtam egy sebességi referenciaértékhez. Az itt található sed válaszok tökéletesen megfelelnek az IMO-nak és sokkal jobbak, mint a read.
  • Aliasot is hozzáadhat / etc / profile (vagy a ~ / .bashrc vagy ~ / .zshrc stb …) alias trim = ” awk ‘ { \ $ 1 = \ $ 1}; 1 ‘ ”
  • Nincs szükség a következőre: bash, elkészítheti #! /usr/bin/awk -f {$1=$1};1. (óvakodjon a = karaktereket tartalmazó fájlnevektől)

Válasz

Ha a sorokat változókként tárolja, a bash használatával elvégezheti a munkát:

távolítsa el a vezető szóközöket egy karakterláncból:

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

távolítsa el a záró szóközt a karakterláncból:

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

távolítsa el az összes szóközt a karakterláncból:

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

Megjegyzések

  • Az összes szóköz eltüntetése egy karaktersorozatból nem ugyanaz, mint a vezető és a záró szóköz eltávolítása (mint a kérdéses).
  • A legjobb megoldás – csak bash beépítéseket igényel, és nincs külső folyamatvilla.
  • Szép. A parancsfájlok gyorsabban futtatnak LOT-ot, ha nem ‘ nem kell külső programokat behúzniuk (például awk vagy sed). Ez a ksh ” modern ” (93u +) verzióival is működik.

Válasz

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

Ha egy sort egy héjváltozóba olvas, read ezt már csinálja, hacsak másképp nem rendelkezik .

Megjegyzések

  • +1 a read számára. Tehát, ha az olvasás közben rákapcsol, az működik: cat file | while read i; do echo $i; done
  • @rubo, kivéve a példádban a nem idézett változót a héj is újrafeldolgozza. A echo "$i" paranccsal megnézheted a read

Válasz

Ahhoz, hogy egy “csövezett” eszköznek köszönhetően az adott sorból az összes vezető és záró szóközt eltávolítsam, 3 különböző módok, amelyek nem teljesen egyenértékűek. Ezek a különbségek a beviteli sor szavai közötti terekre vonatkoznak, a várható b függvényében ehaviour, te választasz.

Példák

A különbségek magyarázatához vegye figyelembe ezt a dummy beviteli sort:

" \t A \tB\tC \t " 

tr

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

tr valóban egyszerű parancs. Ebben az esetben töröl bármilyen szóközt vagy táblázatos karaktert.

awk

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

awk törli a vezető és a farokközöket, és egyetlen szóközbe szorítja a szavak közötti minden szóközt.

sed

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

Ebben az esetben sed törli a vezető és a farok tereket anélkül, hogy a szavak között szóközöket érintene.

Megjegyzés:

Soronként egy szó esetén a tr végzi a munkát.

Megjegyzések

  • Ez azonban egyiket sem vonja be az új sorok mögé / elé.
  • +1 a (néha váratlan) kimenettel rendelkező megoldások listájához.
  • @ user61382 ez meglehetősen késő, de nézze meg az eredeti bejegyzéshez fűzött megjegyzésemet.
  • @highmaintenance: a <: id:>

helyett használja a [: blank:] parancsot atr, például:... | tr -d [:space:], az új sorok eltávolításához is. (lásd:

man tr)

Válasz

a sed egy nagyszerű eszköz erre:

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

Használhatja esetére, legyen szó akár a szöveg beillesztéséről, pl.

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

vagy “soronként” cselekszik, ha az sed a GNU:

sed -i "s/..." file 

de a forrás ilyen módon történő megváltoztatása “veszélyes”, mivel lehet, hogy helyrehozhatatlan, ha nem működik jól (vagy akkor is, amikor működik!), ezért először készítsen biztonsági másolatot (vagy használja a -i.bak, amelynek az is előnye, hogy néhány BSD-re hordozható sed s)!

Válasz

Egy pillanat alatt megérthető válasz:

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

Bónusz: cserélje le str.strip([chars]) tetszőleges karakterekkel a .lstrip() vagy .rstrip() vágásához vagy szükség szerinti használatához.

Mint rubo77 “sa nswer , mentse szkriptként /usr/local/bin/trim és adjon engedélyeket a chmod +x paranccsal.

Válasz

Ha az a karaktersorozat, amelyet megpróbál vágni, rövid és folytonos / összefüggő, egyszerűen átadhatja paraméterként bármely bash függvényre:

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

Válasz

Ezt a shell függvényt írtam awk

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

BEGIN{ RS="^$" }:
a rekord elemzése és az elválasztó elemzése előtt az elemzés megkezdése előtt azaz a teljes bevitelt
egyetlen rekordként kezelje.

gsub(this,that):
cserélje le ezt a regexpet arra a karakterláncra

/^[\n\t ]*|[\n\t ]*$/: ennek a karaktersorozatnak az elõzõ újsoros szóköz és fülosztály osztálya elkapja
vagy új sorhelyet és fülosztályt küld, és lecseréli azokat
üres karakterláncra

print;exit: majd nyomtassa ki és lépjen ki

"$1":
és adja át a függvény első argumentumát be
folyamat az awk által

hogyan kell használni:
másolja a kód fölé, illessze be a shellbe, majd írja be a
definíciót a függvény.
akkor az awkcliptor parancsként használhatja az első argumentumot bemeneti fájlként.

minta használat:

echo " ggggg " > a_file awkcliptor a_file 

kimenet:

ggggg 

vagy

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

kimenet:

ggggg 

Megjegyzések

  • Meg tudná magyarázni a különbséget: awk '{$1=$1};1'?

Válasz

Azok számára, akiknek nincs elegendő hely az agyban, hogy emlékezzenek a homályos sed szintaxisra, csak fordítsák meg a karakterláncot , vágja el az 1. mezőt egy térelválasztóval, és fordítsa vissza.

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

Megjegyzések

  • Ez csak akkor működik, ha az egyes soroknál egynél több szóköz és a sorokban legfeljebb egy szó áll.

Válasz

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 

Bónusz: cserélje le a str.strip([chars]) -t tetszőleges karakterekkel a vagy .rstrip() szükség szerint.

Válasz

a fordítás parancs működni fog

cat file | tr -d [:blank:] 

Megjegyzések

  • Ez a parancs nem megfelelő, mert eltávolítja A fájlból minden szóköz, nem csak a szóköz eleje / vége.
  • @BrianRedbeard Igazad van. Ez továbbra is hasznos válasz egy monolit karakterlánc esetében, szóköz nélkül.

Válasz

a bash példához:

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

használat:

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

eredmény:

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

Megjegyzések

  • A awk '{$1=$1};1' választ már régen megadták. Az álnév készítésének gondolata majdnem olyan régen felmerült egy megjegyzésben. Igen, megengedett, hogy valaki más megjegyzését megkapja, és válaszként változtassa meg. De ha mégis megteszi, akkor hitelt kell adnia azoknak az embereknek, akik az ötletet ön előtt feltették. Ez pedig az elfogadott válasz olyan triviális kiterjesztése, hogy valójában nem éri meg a fáradságot.
  • Az ötlet az álnév készítése volt. Nem láttam ‘ ezt a választ korábban.
  • és második dolog a veremből: ” Köszönöm a visszajelzést! A 15-nél kevesebb hírnévvel rendelkezők által leadott szavazatokat rögzítjük, de a nyilvánosan megjelenő bejegyzés pontszámát nem változtatjuk meg. ”

Vélemény, hozzászólás?

Az email címet nem tesszük közzé. A kötelező mezőket * karakterrel jelöltük