2010-12-12 2 views
17

Desidero un modo bash per leggere le righe dall'input standard (in modo che sia possibile reindirizzare l'input) e rimuovere solo i caratteri spazio iniziale e finale. Piping to echo non funziona.Come si leggono le linee di assetto dallo standard input su bash?

Ad esempio, se l'ingresso è:

 12 s3c 
    sd wqr 

l'uscita dovrebbe essere:

12 s3c 
sd wqr 

Voglio evitare di scrivere uno script Python o simile per qualcosa di così banale come questo. Qualsiasi aiuto è apprezzato!

risposta

20

È possibile utilizzare sed per tagliarlo.

sed 's/^ *//;s/ *$//' 

È possibile verificare in realtà facilmente su una riga di comando facendo:

echo -n " 12 s3c " | sed 's/^ *//;s/ *$//' && echo c 
+9

I processi a due sed sono spiacevolmente pesanti. Perché no: 'sed 's/^ * //; s/* $ //''? –

+0

Che funziona contro i dati che ha fornito. Ti ho dato dei punti per questo! : D – phillip

+3

perché nemmeno "sed -r 's/* (. *) */\ 1/g''? –

17
$ trim() { read -r line; echo "$line"; } 
$ echo " aa bb cc " | trim 
aa bb cc 
$ a=$(echo " aa bb cc " | trim) 
$ echo "..$a.." 
..aa bb cc.. 

Per farlo funzionare per input multi-line, basta aggiungere un while ciclo:

trim() { while read -r line; do echo "$line"; done; } 

Utilizzando sed con un solo un sostituzione:

sed 's/^\s*\(.*[^ \t]\)\(\s\+\)*$/\1/' 
+1

Mi piace il semplice approccio di utilità. è necessario correggere la sintassi di while: 'trim() {while read -r line; fai echo "$ line"; fatto; } ' – Barak1731475

+0

@ user1731475: risolto, grazie –

+1

Nota che il punto di questa risposta è 'usa solo il comando di lettura, verrà troncato di default'. L'uso dell'eco è puramente per corrispondere 'l'output dovrebbe essere' condizione di test nella domanda. Per vedere come NON ottenere il comportamento richiesto o capire perché è _possible_ questo potrebbe non funzionare, vedi [questa domanda] (http://stackoverflow.com/questions/7314044/use-bash-to-read-line-by -line-and-keep-spazio). – SensorSmith

3

Aggiungi questa:
| sed -r 's/\s*(.*?)\s*$/\1/'

1

So che questo è vecchio, ma c'è un altro semplice e sporco way:

line=$(echo $line) 

Vedere questo esempio:

[email protected]:~$ x=" abc " 
[email protected]:~$ echo "+$x+" 
+ abc + 
[email protected]:~$ y=$(echo $x) 
[email protected]:~$ echo "$y" 
+abc+ 
+0

Questo è rotto: fallirà se ci sono glob personaggi e concatenerà anche spazi successivi. Non accennando che "echo" è di solito una scelta sbagliata (se, ad esempio, la riga inizia con "-n'," -e' o "-E'). –

+0

Funziona per me. Grazie. – Geddon

1
your_command | xargs -L1 echo 

Questo funziona perché echo converte tutti tabls agli spazi e poi tutti gli spazi multipli in un singolo spazio, non solo iniziali e finali, vedi esempio:

$ printf " 1\t\t\t2 3" 
    1   2 3 
$ echo `printf " 1\t\t\t2 3"` 
1 2 3 

Lo svantaggio è che essa rimuoverà anche alcuni caratteri utili come \'".

+2

Questo fallirà se ci sono backslash o preventivi. –