So ersetzen Sie mehrere Leerzeichen durch einen Tabulator

27

Ich habe einige Textdateien, die einige Spalten enthalten, die durch eine unterschiedliche Anzahl von Leerzeichen voneinander getrennt sind. Stattdessen benötige ich einen einzelnen Tabulator als Trennzeichen. Ist es möglich, in Bash zu tun?

Benutzer unbekannt
quelle
Vielen Dank für die großartige Eingabe, aber ich habe einige einzelne Leerzeichen innerhalb einer Spalte, so muss ich vermeiden, ein einzelnes Leerzeichen zu tabulieren. Entschuldigung, isinformation.
user_unknown

Antworten:

31

So konvertieren Sie Sequenzen von mehr als einem Leerzeichen in einen Tabulator, lassen jedoch einzelne Leerzeichen in Ruhe :

sed 's/ \+ /\t/g' inputfile > outputfile

So führen Sie dies für eine Reihe von Dateien aus:

for inputfile in *
do
    sed 's/ \+ /\t/g' "$inputfile" > tmpfile && mv tmpfile "$inputfile"
done

oder

for inputfile in *
do
    sed -i.bak 's/ \+ /\t/g' "$inputfile"
done

oder

find . -type f -exec sed -i.bak 's/ \+ /\t/g' {} \;
Bis auf weiteres angehalten.
quelle
sed: -e expression #1, char 1: unknown command: `.'
Aaron Franke
@ AaronFranke: Welchen Befehl hast du probiert? Keines der Beispiele in meiner Antwort sollte diesen Fehler hervorrufen.
Bis auf weiteres angehalten.
Entschuldigung, ich hätte das klären sollen. Der findunten.
Aaron Franke
@AaronFranke: GNU sedmöchte kein Leerzeichen vor der Backup-Erweiterung haben. Ich habe meine Antwort bearbeitet. Danke für den Bericht.
Bis auf weiteres angehalten.
6

Wenn Ihr Charakter aus mehreren Registerkarten besteht, können Sie auch Folgendes verwenden tr -s:

-s, --squeeze-repeats   replace each input sequence of a repeated character
                        that is listed in SET1 with a single occurrence

Beispielsweise:

my_file.txt | tr -s " "

Alle Leerzeichen werden eins.

user597119
quelle
Dies ist nicht das, was OP verlangt.
RonJohn
5

Sie können verwenden sed, um mehrere Leerzeichen durch einen Tabulator zu ersetzen:

Beispiel zum Ersetzen von einem oder mehreren Leerzeichen durch eine Registerkarte:

cat spaced-file | sed 's/ \+/\t/g' > tabbed-file
IvanGoneKrazy
quelle
Das OP sagte, die Anzahl der Leerzeichen sei variabel , daher glaube ich nicht, dass diese Lösung funktionieren wird.
Mikel
@Mikel. Hoppla. Vielen Dank für den Hinweis. Ich habe den Beitrag bearbeitet, um den Abgleich für variable Räume zu ermöglichen.
IvanGoneKrazy
Hilfreichste Antwort hier.
Luís de Sousa
3

Die einfachste Antwort bashlautet:

while read -r col1 col2 col3 ...; do
    echo -e "$col1\t$col2\t$col3..."
done <file

Wenn es eine variable Anzahl von Spalten gibt, können Sie dies tun, aber es funktioniert nur in bash, nicht in sh:

while read -r -a cols; do
    (
        IFS=$'\t'
        echo "${cols[*]}"
    )
done <file

z.B

while read -r -a cols; do
    (
        IFS=$'\t'
        echo "${cols[*]}"
    )
done <<EOF
a b   c
d   e    f
  g h i
EOF

produziert:

a   b   c
d   e   f
g   h   i

(Es gibt jeweils einen Tabulator dazwischen, aber es ist schwer zu erkennen, wann ich ihn hier einfügen möchte.)

Sie können dies auch mit sedoder tun. Beachten Sie trjedoch, dass der Umgang mit Leerzeichen zu Beginn zu unterschiedlichen Ergebnissen führt.

sed:

$ sed 's/  */\t/g' << EOF
a b   c
d   e    f
  g h i
EOF
a       b       c
d       e       f
        g       h       i

tr:

$ tr -s ' ' '\t' <<EOF
a b   c
d   e    f
  g h i
EOF
a       b       c
d       e       f
        g       h       i
Mikel
quelle
2

perl -p -i -e 's/\s+/\t/g' *.txt

RedGrittyBrick
quelle
2

Versuchen Sie folgendes SED-Skript:

 sed 's/  */<TAB>/g' <spaces-file > tabs-file

Wobei <TAB> die TAB-Taste drückt.

mdpc
quelle
0

Dies ist eine sehr einfache Lösung:

    sed -E 's/\s+/\t/g' your_file > new_file

sed funktioniert grundsätzlich auf diese Weise (sed 's / old_pattern / new_pattern / g'). In diesem Fall ist das alte Muster "\ s +", was bedeutet, dass "s" einmal oder mehrmals "+" und der umgekehrte Schrägstrich "\" als regulärer Ausdruck interpretiert werden.
Das neue Muster ist die Registerkarte "\ t", die im regulären Ausdrucksformat geschrieben ist, und das "g" wendet die Ersetzung auf alle Zeilen "global" an.

Waleed Omer
quelle
1
Hallo und willkommen beim Superuser. Sie sollten sich die Zeit nehmen, um Ihre Lösung zu erklären. Für jemanden, der nicht mit * nix-Systemen, sed und regulären Ausdrücken vertraut ist, sieht dies wie ein Haufen seltsamer Zeichen aus.
Mogget