Come posso tagliare gli spazi bianchi iniziali e finali da ogni riga di un output?

Vorrei rimuovere tutti gli spazi e le tabulazioni iniziali e finali da ogni riga in un output.

Esiste uno strumento semplice come trim Potrei reindirizzare il mio output in?

File di esempio:

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 

Commenti

  • Per chiunque cerchi qui una soluzione per rimuovere le nuove righe, questo è un problema diverso. Per definizione una nuova riga crea una nuova riga di testo. Pertanto una riga di testo non può contenere una nuova riga. La domanda che vuoi porre è come rimuovere una nuova riga dallinizio o dalla fine di una stringa: stackoverflow.com/questions/369758 o come rimuovere lo spazio vuoto righe o righe che sono solo spazi bianchi: serverfault.com/questions/252921

Risposta

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

o più breve:

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

Taglia linterlinea e spazio finale o caratteri di tabulazione 1 e anche stringere sequenze di tabulazioni e spazi in un unico spazio.

Funziona perché quando assegni qualcosa a uno dei campi , awk ricostruisce lintero record (come stampato da print) unendo tutti i campi ($1, …, $NF) con OFS (spazio per impostazione predefinita).

1 (e possibilmente altro carattere vuoto s a seconda della lingua e dell awk implementazione)

Commenti

  • Punto e virgola su il secondo esempio è superfluo. Potrebbe usare: awk '{$1=$1}1'
  • @Brian, no, ; è richiesto nella sintassi standard di awk
  • Interessante … Nessun punto e virgola è supportato da gawk, mawk e OS X ‘ awk. (Almeno per le mie versioni (1.2, 4.1.1 e 20070501, rispettivamente)
  • Lunica cosa che ‘ non mi piace di questo approccio è che tu perdere spazi ripetuti allinterno della riga. Ad esempio, echo -e 'foo \t bar' | awk '{$1=$1};1'
  • echo ' hello ' | xargs

Risposta

Il comando può essere condensato in questo modo se “stai usando GNU sed:

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

Esempio

Ecco il comando precedente in azione.

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

Puoi utilizzare hexdump per confermare che il comando sed rimuove correttamente i caratteri desiderati.

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

Classi di caratteri

Puoi anche utilizzare nomi di classi di caratteri invece di elencare letteralmente i set come questo, [ \t]:

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

Esempio

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

La maggior parte degli strumenti GNU che fanno uso di expre regolari ssions (regex) supportano queste classi (qui con il loro equivalente nella tipica locale C di un sistema basato su ASCII (e solo lì)).

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

Utilizzo questi invece dei set letterali sembrano sempre uno spreco di spazio, ma se ti preoccupi che il tuo codice sia portabile, o che devi occuparti di set di caratteri alternativi (pensa internazionale), allora probabilmente vorrai usare invece i nomi delle classi .

Riferimenti

Commenti

  • Tieni presente che [[:space:]] non è equivalente a [ \t] nel caso generale (unicode, ecc.). [[:space:]] sarà probabilmente molto più lento (poiché ci sono molti più tipi di spazi bianchi in Unicode oltre a ' ' e '\t'). Stessa cosa per tutti gli altri.
  • sed 's/^[ \t]*//' non è portabile. Attualmente POSIX richiede anche di rimuovere una sequenza di spazio, barra rovesciata o t caratteri e che ‘ è ciò che GNU sed funziona anche quando POSIXLY_CORRECT è nellambiente.
  • E se volessi tagliare i caratteri di nuova riga? ‘ \ n \ n text \ n \ n ‘
  • Mi piace la soluzione sed per la mancanza di altri effetti collaterali come nella soluzione awk. La prima variazione non funziona quando lho provata in bash su OSX jsut ora, ma la versione della classe dei caratteri funziona: sed 's/^[[:blank:]]*//;s/[[:blank:]]*$//'
  • @EugeneBiryukov vedi il mio commento su il post originale

Answer

xargs senza argomenti lo fa.

Esempio:

trimmed_string=$(echo "no_trimmed_string" | xargs) 

Commenti

  • Questo inoltre contrae più spazi allinterno una riga, che non era richiesta nella domanda
  • @roaima – true ma la risposta accettata comprime anche gli spazi (che non era richiesta nella domanda). Penso che il vero problema qui sia che xargs non verrà pubblicato se linput contiene barre rovesciate e virgolette singole.
  • @don_crissti che non ‘ significa che la risposta accettata risponde correttamente alla domanda così come è stata posta. Ma in questo caso qui non è stato ‘ contrassegnato come avvertimento, mentre nella risposta accettata lo era. Spero che ‘ abbia evidenziato il fatto nel caso in cui ‘ sia rilevante per un lettore futuro.
  • interruzioni su virgolette singole, virgolette doppie, caratteri backslash. Esegue anche una o più invocazioni echo. Alcune implementazioni echo elaboreranno anche opzioni e / o barre rovesciate … Funziona anche solo per input su una riga.

Risposta

Come suggerito da Stéphane Chazelas nella risposta accettata, ora puoi
creare uno script /usr/local/bin/trim:

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

e concedi a quel file i diritti di eseguibile:

chmod +x /usr/local/bin/trim 

Ora puoi passare ogni output a trim ad esempio:

cat file | trim 

(per i commenti di seguito: lho usato prima: while read i; do echo "$i"; done
che funziona anche bene, ma è meno performante)

Commenti

  • Buona fortuna se il tuo file è enorme e / o contiene barre rovesciate.
  • @don_crissti: potresti commentare un po di più ?, quale soluzione sarebbe si adatta meglio a file di grandi dimensioni e come posso modificare la mia soluzione se il file contenga barre rovesciate?
  • ‘ dovrai utilizzare while read -r line per preservare le barre rovesciate e anche in questo caso … . Per quanto riguarda file / velocità enormi, in realtà, hai scelto la soluzione peggiore. Non ‘ credo che ‘ ci sia qualcosa di peggio là fuori. Vedi le risposte su Perché utilizzare un ciclo di shell per elaborare il testo è una cattiva pratica? incluso il mio commento sullultima risposta in cui ho aggiunto un collegamento a un benchmark di velocità. Le risposte sed qui vanno benissimo IMO e di gran lunga migliori di read.
  • Puoi anche aggiungere un alias in / etc / profile (o il tuo ~ / .bashrc o ~ / .zshrc ecc …) alias trim = ” awk ‘ { \ $ 1 = \ $ 1}; 1 ‘ ”
  • Non è necessario bash, puoi impostarlo come #! /usr/bin/awk -f {$1=$1};1. (attenzione però ai nomi di file contenenti = caratteri)

Risposta

Se memorizzi le righe come variabili, puoi utilizzare bash per eseguire il lavoro:

rimuovi gli spazi bianchi iniziali da una stringa:

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

rimuovi gli spazi vuoti finali da una stringa:

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

rimuovi tutti gli spazi bianchi da una stringa:

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

Commenti

  • Rimuovere tutti gli spazi bianchi da una stringa non equivale a rimuovere gli spazi iniziali e finali (come nella domanda).
  • Di gran lunga la soluzione migliore: richiede solo builtin bash e nessun fork di processo esterno.
  • Bello. Gli script vengono eseguiti MOLTO più velocemente se ‘ non devono inserire programmi esterni (come awk o sed). Funziona anche con le ” moderne ” (93u +) versioni di ksh.

Risposta

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

Se “stai leggendo una riga in una variabile di shell, read lo fa già se non diversamente indicato .

Commenti

  • +1 per read. Quindi, se continui a leggere, funziona: cat file | while read i; do echo $i; done
  • @rubo tranne che nel tuo esempio la variabile non quotata viene rielaborata anche dalla shell. Utilizza echo "$i" per vedere il vero effetto del read

Answer

Per rimuovere tutti gli spazi iniziali e finali da una data riga grazie a uno strumento “piped”, posso identificare 3 diversi modi che non sono completamente equivalenti Queste differenze riguardano gli spazi tra le parole della riga di input A seconda del previsto b comportamento, farai la tua scelta.

Esempi

Per spiegare le differenze, si consideri questa riga di input fittizia:

" \t A \tB\tC \t " 

tr

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

tr è davvero un semplice comando. In questo caso, elimina qualsiasi carattere di spazio o di tabulazione.

awk

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

awk elimina gli spazi iniziali e finali e riduce a un singolo spazio ogni spazio tra le parole.

sed

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

In questo caso, sed elimina gli spazi iniziali e finali senza toccare gli spazi tra le parole.

Nota:

Nel caso di una parola per riga, tr fa il lavoro.

Commenti

  • Niente di tutto questo taglia le nuove righe finali / iniziali anche se
  • +1 per un elenco di soluzioni con il loro output (a volte inaspettato).
  • @ user61382 è piuttosto tardi, ma vedi il mio commento sul post originale.
  • @highmaintenance: usa [:space:], invece di [: blank:], per il comando tr, ad esempio: ... | tr -d [:space:], per rimuovere anche le nuove righe. (vedi: man tr)

Risposta

sed è un ottimo strumento per questo:

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

Puoi usarlo per il tuo caso sia nelle tubazioni nel testo, ad esempio

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

o agendo su di esso “inline” se il tuo sed è quello GNU:

sed -i "s/..." file 

ma cambiare lorigine in questo modo è “pericoloso” in quanto potrebbe essere irrecuperabile quando non funziona correttamente (o anche quando funziona!), quindi esegui prima il backup (o usa -i.bak che ha anche il vantaggio di essere portabile su alcuni sed s)!

Risposta

Una risposta che puoi capire a colpo docchio:

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

Bonus: sostituire str.strip([chars]) con caratteri arbitrari per tagliare o utilizzare .lstrip() o .rstrip() secondo necessità.

Come rubo77 “sa nswer , salva come script /usr/local/bin/trim e concedi le autorizzazioni con chmod +x.

Risposta

Se la stringa che si sta cercando di tagliare è corta e continua / contigua, è possibile passarla semplicemente come parametro a qualsiasi funzione bash:

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

Answer

Ho scritto questa funzione shell usando awk

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

BEGIN{ RS="^$" }:
allinizio prima di iniziare lanalisi imposta il separatore del record
su nessuno vale a dire tratta lintero input come
un singolo record

gsub(this,that):
sostituisci questa espressione regolare con quella stringa

/^[\n\t ]*|[\n\t ]*$/:
di quella stringa cattura qualsiasi spazio prima di una nuova riga e classe di tabulazione
o pubblica spazio di nuova riga e classe di tabulazione e sostituiscili con una stringa vuota

print;exit: quindi stampa ed esci

"$1":
e passa il primo argomento della funzione a essere
process by awk

come usare:
copia il codice sopra, incollalo nella shell e poi inserisci
definire la funzione.
quindi puoi utilizzare awkcliptor come comando con il primo argomento come file di input

utilizzo di esempio:

echo " ggggg " > a_file awkcliptor a_file 

output:

ggggg 

o

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

output:

ggggg 

Commenti

  • Puoi spiegare la differenza solo con awk '{$1=$1};1'?

Risposta

Per quelli di noi che non hanno abbastanza spazio nel cervello per ricordare loscura sintassi di sed, basta invertire la stringa , taglia il primo campo con un delimitatore di spazio e invertilo di nuovo.

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

Commenti

  • Funziona solo se non cè più di uno spazio allinizio di ogni riga e non più di una parola in ogni riga.

Risposta

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: sostituire str.strip([chars]) con caratteri arbitrari per tagliare o utilizzare o .rstrip() secondo necessità.

Rispondi

il comando translate funzionerebbe

cat file | tr -d [:blank:] 

Commenti

  • Questo comando non è corretto in quanto rimuove tutti gli spazi dal file, non solo gli spazi iniziali / finali.
  • @BrianRedbeard Hai ragione. Questa è ancora una risposta utile per una stringa monolitica, senza spazi.

Risposta

per esempio bash:

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

utilizzo:

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

risultato:

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

Commenti

  • La risposta awk '{$1=$1};1' è stata data molto tempo fa. Lidea di ricavarne uno pseudonimo è stata suggerita in un commento quasi tanto tempo fa. Sì, puoi prendere il commento di qualcun altro e trasformarlo in una risposta. Ma, se lo fai, dovresti dare credito alle persone che hanno pubblicato lidea prima di te. E questa è unestensione così banale della risposta accettata che non ne vale davvero la pena.
  • Lidea era di fare uno pseudonimo. ‘ non ho visto quella risposta prima.
  • e la seconda cosa dallo stack: ” Grazie per il feedback! I voti espressi da coloro con meno di 15 reputazione vengono registrati, ma non cambia il punteggio del post visualizzato pubblicamente. ”

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *