it-swarm.com.de

Wie schneide ich führende und nachfolgende Leerzeichen aus jeder Zeile einer Ausgabe ab?

Ich möchte alle führenden und nachfolgenden Leerzeichen und Tabulatoren aus jeder Zeile in einer Ausgabe entfernen.

Gibt es ein einfaches Tool wie trim, in das ich meine Ausgabe leiten könnte?

Beispieldatei:

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 
189
rubo77
awk '{$1=$1;print}'

oder kürzer:

awk '{$1=$1};1'

Würde führende und nachfolgende Leerzeichen oder Tabulatorzeichen kürzen1 nd auch Drücken Sie Sequenzen von Tabulatoren und Leerzeichen in ein einzelnes Leerzeichen.

Das funktioniert, weil, wenn Sie einem der Felder etwas zuweisen, awk den gesamten Datensatz (wie von print gedruckt) neu erstellt, indem alle Felder ($1, ..., $NF) mit OFS (standardmäßig Leerzeichen).

1(und möglicherweise andere leere Zeichen, abhängig vom Gebietsschema und der Implementierung von awk)

242

Der Befehl kann wie folgt komprimiert werden, wenn Sie GNU sed:

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

Beispiel

Hier ist der obige Befehl in Aktion.

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

Mit hexdump können Sie bestätigen, dass der Befehl sed die gewünschten Zeichen korrekt entfernt.

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

Zeichenklassen

Sie können auch Zeichenklassennamen verwenden, anstatt die Sätze wie folgt buchstäblich aufzulisten: [ \t]:

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

Beispiel

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

Die meisten Tools GNU], die reguläre Ausdrücke (Regex) verwenden, unterstützen diese Klassen.

 [[:alnum:]]  - [A-Za-z0-9]     Alphanumeric characters
 [[:alpha:]]  - [A-Za-z]        Alphabetic characters
 [[:blank:]]  - [ \x09]         Space or tab characters only
 [[:cntrl:]]  - [\x00-\x19\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:]]  - [!-/:[email protected][-`{-~]  Punctuation characters
 [[:space:]]  - [ \t\v\f]       All whitespace chars
 [[:upper:]]  - [A-Z]           Upper-case alphabetic characters
 [[:xdigit:]] - [0-9a-fA-F]     Hexadecimal digit characters

Die Verwendung dieser anstelle von Literalmengen scheint immer eine Verschwendung von Speicherplatz zu sein. Wenn Sie jedoch Bedenken haben, dass Ihr Code portabel ist oder sich mit alternativen Zeichensätzen befassen muss (denken Sie international), sollten Sie wahrscheinlich die Klassennamen verwenden stattdessen.

Verweise

57
slm

xargs ohne Argumente machen das.

Beispiel:

trimmed_string=$(echo "no_trimmed_string" | xargs) 
27
Newton_Jose

Wie von Stéphane Chazelas in der akzeptierten Antwort vorgeschlagen, können Sie jetzt
ein Skript erstellen /usr/local/bin/trim:

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

und geben Sie dieser Datei ausführbare Rechte:

chmod +x /usr/local/bin/trim

Jetzt können Sie jede Ausgabe an trim übergeben, zum Beispiel:

cat file | trim

(für die folgenden Kommentare: Ich habe dies zuvor verwendet: while read i; do echo "$i"; done
was auch gut funktioniert, aber weniger performant ist)

25
rubo77
sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//'

Wenn Sie eine Zeile in eine Shell-Variable einlesen, erledigt read dies bereits sofern nicht anders angegeben .

Wenn Sie Zeilen als Variablen speichern, können Sie den Job mit bash ausführen:

entfernen Sie führende Leerzeichen aus einer Zeichenfolge:

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

entfernen Sie nachgestellte Leerzeichen aus einer Zeichenfolge:

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

entfernen Sie alle Leerzeichen aus einer Zeichenfolge:

echo ${text//[[:space:]]}
17
Łukasz Rajchel

Um dank eines 'Piped'-Tools alle führenden und nachfolgenden Leerzeichen aus einer bestimmten Zeile zu entfernen, kann ich drei verschiedene Arten identifizieren, die nicht vollständig gleichwertig sind. Diese Unterschiede betreffen die Leerzeichen zwischen den Wörtern der Eingabezeile. Abhängig vom erwarteten Verhalten treffen Sie Ihre Wahl.

Beispiele

Betrachten Sie diese Dummy-Eingabezeile, um die Unterschiede zu erklären:

"   \t  A   \tB\tC   \t  "

tr

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

tr ist wirklich ein einfacher Befehl. In diesem Fall werden Leerzeichen oder Tabellierungszeichen gelöscht.

awk

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

awk löscht führende und abschließende Leerzeichen und drückt alle Leerzeichen zwischen Wörtern auf ein einzelnes Leerzeichen.

sed

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

In diesem Fall löscht sed führende und hintere Leerzeichen, ohne Leerzeichen zwischen Wörtern zu berühren.

Bemerkung :

Bei einem Wort pro Zeile erledigt tr die Aufgabe.

15
frozar

sed ist ein großartiges Werkzeug dafür:

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

Sie können es für Ihren Fall verwenden, indem Sie entweder den Text weiterleiten, z.

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

oder indem Sie 'inline' darauf einwirken, wenn Ihr sed das GNU one) ist:

sed -i 's/...' file

das Ändern der Quelle auf diese Weise ist jedoch "gefährlich", da es möglicherweise nicht wiederherstellbar ist, wenn es nicht richtig funktioniert (oder sogar wenn es funktioniert!). Sichern Sie also zuerst (oder verwenden Sie -i.bak was auch den Vorteil hat, auf einige BSDs portierbar zu sein seds)!

6
Michael Durrant

Eine Antwort, die Sie auf einen Blick verstehen können:

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

Bonus: Ersetzen Sie str.strip([chars]) durch beliebige Zeichen, um .lstrip() oder .rstrip() nach Bedarf zu trimmen oder zu verwenden.

Wie Antwort von rubo77 , als Skript speichern /usr/local/bin/trim Und Berechtigungen mit chmod +x Erteilen.

4
qwr

der Befehl translate würde funktionieren

cat file | tr -d [:blank:]
2
Srinagesh

Ich habe diese Shell-Funktion mit awk geschrieben

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

BEGIN{ RS="^$" }:
am Anfang vor dem Parsen des eingestellten Datensatzes
Trennzeichen zu keiner, d. h. die gesamte Eingabe als behandeln
eine einzelne Aufzeichnung

gsub(this,that):
Ersetzen Sie diesen regulären Ausdruck durch diese Zeichenfolge

/^[\n\t ]*|[\n\t ]*$/:
dieser Zeichenfolge fängt alle vor dem Zeilenumbruch stehenden Leerzeichen und Tabulatorklassen ab
oder schreiben Sie Zeilenumbruch und Tabulatorklasse und ersetzen Sie sie durch
leerer String

print;exit: Dann drucken und beenden

"$1":
und übergeben Sie das erste Argument der Funktion zu sein
Prozess von awk

wie benutzt man:
Kopieren Sie den obigen Code, fügen Sie ihn in Shell ein und geben Sie dann ein
definieren die Funktion.
Dann können Sie awkcliptor als Befehl mit dem ersten Argument als Eingabedatei verwenden

beispielnutzung:

echo '
 ggggg    

      ' > a_file
awkcliptor a_file

ausgabe:

ggggg

oder

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

ausgabe:

ggggg

Wenn die Zeichenfolge, die getrimmt werden soll, kurz und kontinuierlich/zusammenhängend ist, kann sie einfach als Parameter an eine beliebige Bash-Funktion übergeben werden:

    trim(){
        echo [email protected]
    }

    a="     some random string   "

    echo ">>`trim $a`<<"
Output
>>some random string<<
1
Subrata Das
trimpy () {
    python3 -c 'import sys
for line in sys.stdin: print(line.strip())'
}
trimsed () {
gsed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//'
}
# example usage
echo " hi " | trimpy

Bonus: Ersetzen Sie str.strip([chars]) durch beliebige Zeichen, um .lstrip() oder .rstrip() nach Bedarf zu trimmen oder zu verwenden.

(Dies ist nur ein Remix anderer Antworten hier.)

0
HappyFace