Aș dori să șterg toate spațiile și filele din partea de sus și de pe fiecare linie dintr-o ieșire.
Există un instrument simplu ca trim
Mi-aș putea introduce ieșirea în?
Exemplu de fișier:
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
Comentarii
- Pentru oricine caută aici o soluție pentru eliminarea liniilor noi, aceasta este o problemă diferită. Prin definiție, o linie nouă creează o nouă linie de text. Prin urmare, o linie de text nu poate conține o linie nouă. Întrebarea pe care doriți să o puneți este cum să eliminați o linie nouă de la începutul sau sfârșitul unui șir: stackoverflow.com/questions/369758 sau cum să eliminați golul linii sau linii care sunt doar spații albe: serverfault.com/questions/252921
Răspuns
awk "{$1=$1;print}"
sau mai scurt:
awk "{$1=$1};1"
Ar tăia primul și spațiu final sau caractere tab 1 și, de asemenea, stoarce secvențe de file și spații într-un singur spațiu.
Acest lucru funcționează deoarece atunci când atribuiți ceva unuia dintre câmpurile , awk
reconstruiește întregul record (așa cum este tipărit de print
) prin alăturarea tuturor câmpurilor ($1
, …, $NF
) cu OFS
(spațiu implicit).
1 (și, eventual, alt caracter gol depinde de localizare și de implementarea awk
)
Comentarii
- Punct și virgulă pe al doilea exemplu este de prisos. S-ar putea folosi:
awk '{$1=$1}1'
- @Brian, nu,
;
este necesar în sintaxa standard awk - Interesant … Niciun punct și virgulă nu este acceptat de gawk, mawk și OS X ‘ s awk. (Cel puțin pentru versiunile mele (1.2, 4.1.1 și, respectiv, 20070501)
- Singurul lucru care nu îmi place ‘ nu este că această abordare este pierdeți spațiile repetate din linie. De exemplu,
echo -e 'foo \t bar' | awk '{$1=$1};1'
-
echo ' hello ' | xargs
Răspuns
Comanda poate fi condensată așa dacă folosiți GNU sed
:
$ sed "s/^[ \t]*//;s/[ \t]*$//" < file
Exemplu
Aici este comanda de mai sus în acțiune.
$ echo -e " \t blahblah \t " | sed "s/^[ \t]*//;s/[ \t]*$//" blahblah
Puteți utiliza hexdump
pentru a confirma că comanda sed
elimină corect caracterele dorite.
$ echo -e " \t blahblah \t " | sed "s/^[ \t]*//;s/[ \t]*$//" | hexdump -C 00000000 62 6c 61 68 62 6c 61 68 0a |blahblah.| 00000009
Clase de caractere
Puteți utiliza și nume de clase de caractere în loc să enumerați literalmente seturile astfel, [ \t]
:
$ sed "s/^[[:blank:]]*//;s/[[:blank:]]*$//" < file
Exemplu
$ echo -e " \t blahblah \t " | sed "s/^[[:blank:]]*//;s/[[:blank:]]*$//"
Majoritatea instrumentelor GNU care folosesc expre obișnuite ssions (regex) acceptă aceste clase (aici cu echivalentul lor în localizarea tipică C a unui sistem bazat pe ASCII (și numai acolo)).
[[: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
aceste seturi în loc de literal pare întotdeauna o pierdere de spațiu, dar dacă sunteți îngrijorat de faptul că codul dvs. este portabil sau trebuie să aveți de-a face cu seturi de caractere alternative (gândiți-vă internațional), atunci veți dori probabil să folosiți numele claselor în loc .
Referințe
Comentarii
- Rețineți că
[[:space:]]
nu este echivalent cu[ \t]
caz general (unicode, etc).[[:space:]]
va fi probabil mult mai lent (deoarece există mult mai multe tipuri de spații albe în unicode decât doar' '
și'\t'
). Același lucru pentru toate celelalte. -
sed 's/^[ \t]*//'
nu este portabil. În realitate POSIX necesită chiar și pentru a elimina o secvență de spațiu, backslash saut
caractere și că ‘ este ceea ce este GNU 51efbcd6df „>
funcționează și atunci cândPOSIXLY_CORRECT
se află în mediul înconjurător.
sed 's/^[[:blank:]]*//;s/[[:blank:]]*$//'
Răspuns
xargs fără argumente face asta.
Exemplu:
trimmed_string=$(echo "no_trimmed_string" | xargs)
Comentarii
- De asemenea, aceasta contractează mai multe spații în o linie, care nu a fost solicitată la întrebarea
- @roaima – adevărat, dar răspunsul acceptat stoarce și spații (ceea ce nu a fost solicitat în întrebare). Cred că adevărata problemă aici este că
xargs
nu va putea fi livrat dacă intrarea conține bare oblice și ghilimele simple. - @don_crissti care nu ‘ t înseamnă că răspunsul acceptat răspunde corect la întrebarea așa cum a fost pusă. Dar în acest caz aici nu a fost ‘ t marcat ca o avertizare, în timp ce în răspunsul acceptat a fost. Am ‘ sper că am evidențiat faptul că ‘ este relevant pentru un viitor cititor.
- De asemenea, pauze pe ghilimele unice, ghilimele duble, caractere inversă. De asemenea, rulează una sau mai multe invocații
echo
. Unele implementări de ecou vor procesa, de asemenea, opțiuni și / sau backslash … Acest lucru funcționează și pentru intrarea cu o singură linie.
Răspuns
Așa cum sugerează Stéphane Chazelas în răspunsul acceptat, acum puteți crea un script /usr/local/bin/trim
:
#!/bin/bash awk "{$1=$1};1"
și acordați acel fișier drepturi executabile:
chmod +x /usr/local/bin/trim
Acum puteți transmite fiecare ieșire către trim
de exemplu:
cat file | trim
(pentru comentariile de mai jos: am folosit acest lucru înainte: while read i; do echo "$i"; done
care funcționează și bine, dar este mai puțin performant)
Comentarii
- Noroc dacă fișierul dvs. este imens și / sau conține bare oblice.
- @don_crissti: ați putea comenta ceva mai mult ?, ce soluție ar fi să fie mai potrivit pentru fișierele uriașe și cum aș putea modifica soluția dacă fișierul conținea bare oblice?
- ‘ va trebui să utilizați
while read -r line
pentru a păstra bare oblice și chiar și atunci … . În ceea ce privește fișierele imense / viteza, într-adevăr, ați ales cea mai proastă soluție. Nu ‘ nu cred că există ‘ ceva mai rău acolo. Vedeți răspunsurile de pe De ce se folosește o buclă de shell pentru a procesa o practică nepotrivită a textului? , inclusiv comentariul meu la ultimul răspuns în care am adăugat un link la un indicator de viteză. Răspunsurilesed
aici sunt perfect IMO și sunt mult mai bune decâtread
. - De asemenea, puteți adăuga un alias în / etc / profile (sau ~ / .bashrc sau ~ / .zshrc etc …) alias trim = ” awk ‘ { \ $ 1 = \ $ 1}; 1 ‘ ”
- Nu este nevoie de
bash
, îl puteți face#! /usr/bin/awk -f
{$1=$1};1
. (feriți-vă de numele fișierelor care conțin=
caractere)
Răspuns
Dacă stocați liniile ca variabile, puteți utiliza bash pentru a face treaba:
eliminați spațiul alb principal dintr-un șir:
shopt -s extglob echo ${text##+([[:space:]])}
eliminați spațiul alb dintr-un șir:
shopt -s extglob echo ${text%%+([[:space:]])}
eliminați tot spațiul alb dintr-un șir:
echo ${text//[[:space:]]}
Comentarii
- Eliminarea întregului spațiu alb dintr-un șir nu este același lucru cu eliminarea atât a spațiilor de început, cât și a celei de final (ca în întrebare).
- De departe cea mai bună soluție – necesită doar elemente integrate bash și fără furci de proces externe.
- Frumos. Scripturile rulează MULȚI mai repede dacă nu ‘ nu trebuie să extragă programe externe (cum ar fi awk sau sed). Acest lucru funcționează și cu versiunile ” moderne ” (93u +) ale ksh.
Răspuns
sed -e "s/^[[:space:]]*//" -e "s/[[:space:]]*$//"
Dacă citești o linie într-o variabilă shell, read
face asta deja dacă nu este indicat altfel .
Comentarii
- +1 pentru
read
. Deci, dacă citiți în timp ce citiți, funcționează:cat file | while read i; do echo $i; done
- @rubo cu excepția faptului că în exemplul dvs., variabila necitată este, de asemenea, reprocesată de shell. Utilizați
echo "$i"
pentru a vedea adevăratul efect alread
Răspuns
Pentru a elimina toate spațiile de la începutul și de la o linie dată datorită unui instrument „cu conductă”, pot identifica 3 diferite moduri care nu sunt complet echivalente. Aceste diferențe se referă la spațiile dintre cuvintele liniei de intrare. În funcție de b așteptat comportament, vei face alegerea ta.
Exemple
Pentru a explica diferențele, să luăm în considerare această linie de intrare fictivă:
" \t A \tB\tC \t "
tr
$ echo -e " \t A \tB\tC \t " | tr -d "[:blank:]" ABC
tr
este într-adevăr o comandă simplă. În acest caz, șterge orice spațiu sau caracter de tabelare.
awk
$ echo -e " \t A \tB\tC \t " | awk "{$1=$1};1" A B C
awk
șterge spațiile de conducere și de coadă și stoarce într-un singur spațiu fiecare spațiu dintre cuvinte.
sed
$ echo -e " \t A \tB\tC \t " | sed "s/^[ \t]*//;s/[ \t]*$//" A B C
În acest caz, sed
șterge spațiile de direcție și coadă fără a atinge spații între cuvinte.
Observație:
În cazul unui cuvânt pe linie, tr
face treaba.
Comentarii
- Niciunul dintre aceste elemente nu urmărește / conduce linii noi, deși
- +1 pentru o listă de soluții cu ieșirea lor (uneori neașteptată).
- @ user61382 acest lucru este destul de târziu, dar vedeți comentariul meu la postarea originală.
- @highmaintenance: utilizați
[:space:]
, în loc de [: blank:], pentru comandatr
, cum ar fi:... | tr -d [:space:]
, pentru a elimina și liniile noi. (vezi:man tr
)
Răspuns
sed este un instrument excelent pentru asta:
# substitute ("s/") sed "s/^[[:blank:]]*//; # parts of lines that start ("^") with a space/tab s/[[:blank:]]*$//" # or end ("$") with a space/tab # with nothing (/)
Puteți să-l utilizați pentru cazul dvs. fie în canal, fie în text, de ex.
<file sed -e "s/^[[...
sau acționând pe acesta „inline” dacă sed
este cel GNU:
sed -i "s/..." file
dar schimbarea sursei în acest fel este „periculoasă”, deoarece poate fi nerecuperabilă atunci când nu funcționează corect (sau chiar și atunci când funcționează!), deci faceți mai întâi copie de rezervă (sau utilizați -i.bak
care are și avantajul de a fi portabil pentru unele BSD sed
s)!
Răspuns
Un răspuns pe care îl puteți înțelege dintr-o privire:
#!/usr/bin/env python3 import sys for line in sys.stdin: print(line.strip())
Bonus: înlocuiți str.strip([chars])
cu caractere arbitrare pentru a tăia sau utiliza .lstrip()
sau .rstrip()
după cum este necesar.
Ca rubo77 „sa nswer , salvați ca script /usr/local/bin/trim
și dați permisiunile cu chmod +x
.
Răspuns
Dacă șirul pe care încercăm să-l tăiem este scurt și continuu / contigu, îl puteți trece pur și simplu ca parametru la orice funcție bash:
trim(){ echo $@ } a=" some random string " echo ">>`trim $a`<<" Output >>some random string<<
Răspuns
Am scris această funcție shell folosind awk
awkcliptor(){ awk -e "BEGIN{ RS="^$" } {gsub(/^[\n\t ]*|[\n\t ]*$/,"");print ;exit}" "$1" ; }
BEGIN{ RS="^$" }
:
la început înainte de a începe analiza setează înregistrarea
separator la none adică tratează întreaga intrare ca
o singură înregistrare
gsub(this,that)
:
înlocuiește această regexp cu acel șir
/^[\n\t ]*|[\n\t ]*$/
:
din acel șir captează orice spațiu înainte de linie nouă și clasă de file
sau postează spațiu de linie nouă și clasă de file și le înlocuiește cu
șir gol
print;exit
: apoi tipăriți și ieșiți
"$1"
:
și treceți primul argument al funcției către fiți proces de awk
cum să utilizați:
copiați codul de mai sus, lipiți în shell, apoi introduceți pentru a defini
funcția.
atunci puteți utiliza awkcliptor ca o comandă cu primul argument ca fișier de intrare
utilizare eșantion:
echo " ggggg " > a_file awkcliptor a_file
ieșire:
ggggg
sau
echo -e "\n ggggg \n\n "|awkcliptor
ieșire:
ggggg
Comentarii
- Puteți explica diferența doar
awk '{$1=$1};1'
?
Răspuns
Pentru cei dintre noi fără suficient spațiu în creier pentru a ne aminti sintaxa sed obscură, inversați șirul , tăiați primul câmp cu un delimitator de spațiu și inversați-l din nou.
cat file | rev | cut -d" " -f1 | rev
Comentarii
- Acest lucru funcționează numai dacă nu există mai mult de un spațiu care conduce fiecare linie și nu mai mult de un cuvânt în orice linie.
Răspuns
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: înlocuiți str.strip([chars])
cu caractere arbitrare pentru a tăia sau utiliza sau .rstrip()
după cum este necesar.
Răspuns
comanda de traducere ar funcționa
cat file | tr -d [:blank:]
Comentarii
- Această comandă nu este corectă deoarece elimină Toate spațiile din fișier, nu doar spațiul alb principal / final.
- @BrianRedbeard Aveți dreptate. Acesta este încă un răspuns util pentru un șir monolitic, fără spații.
Răspuns
pentru exemplu bash:
alias trim="awk "{\$1=\$1};1""
utilizare:
echo -e " hello\t\tkitty " | trim | hexdump -C
rezultat:
00000000 68 65 6c 6c 6f 20 6b 69 74 74 79 0a |hello kitty.| 0000000c
Comentarii
- Răspunsul
awk '{$1=$1};1'
a fost dat cu mult timp în urmă. Ideea de a crea un alias din acesta a fost sugerată într-un comentariu aproape la fel de demult. Da, aveți voie să luați comentariile altcuiva și să le transformați într-un răspuns. Dar, dacă o faceți, ar trebui să acordați credit persoanelor care au postat ideea în fața dvs. Și aceasta este o extensie atât de banală a răspunsului acceptat, încât nu merită să te deranjezi. - Ideea era să faci un alias. ‘ nu am mai văzut răspunsul anterior.
- și al doilea lucru din stivă: ” Vă mulțumim pentru feedback! Voturile exprimate de cei cu o reputație mai mică de 15 sunt înregistrate, dar nu modifică scorul afișat public. ”