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 at
karakterek eltávolításához, és hogy ‘ legyen az, amit a GNU akkor is megteszi, haPOSIXLY_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 aread
. - 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 aread
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. ”