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?
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?
Antworten:
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' {} \;
sed: -e expression #1, char 1: unknown command: `.'
find
unten.
sed
möchte kein Leerzeichen vor der Backup-Erweiterung haben. Ich habe meine Antwort bearbeitet. Danke für den Bericht.
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.
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
Die einfachste Antwort bash
lautet:
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 sed
oder tun. Beachten Sie tr
jedoch, 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
perl -p -i -e 's/\s+/\t/g' *.txt
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.