Ersetzen Sie Leerzeichen durch Tabulatoren unter Linux

98

Wie ersetze ich Whitespaces in einer bestimmten Textdatei durch Tabulatoren unter Linux?

biznez
quelle

Antworten:

167

Verwenden Sie das Programm nicht erweitern (1)


UNEXPAND(1)                      User Commands                     UNEXPAND(1)

NAME
       unexpand - convert spaces to tabs

SYNOPSIS
       unexpand [OPTION]... [FILE]...

DESCRIPTION
       Convert  blanks in each FILE to tabs, writing to standard output.  With
       no FILE, or when FILE is -, read standard input.

       Mandatory arguments to long options are  mandatory  for  short  options
       too.

       -a, --all
              convert all blanks, instead of just initial blanks

       --first-only
              convert only leading sequences of blanks (overrides -a)

       -t, --tabs=N
              have tabs N characters apart instead of 8 (enables -a)

       -t, --tabs=LIST
              use comma separated LIST of tab positions (enables -a)

       --help display this help and exit

       --version
              output version information and exit
. . .
STANDARDS
       The expand and unexpand utilities conform to IEEE Std 1003.1-2001
       (``POSIX.1'').
DigitalRoss
quelle
4
Woah, ich wusste nie, dass es Expansion / Unexpand gibt. Ich habe versucht, das Gegenteil zu tun und zu expandieren war perfekt, anstatt mit troder herumspielen zu müssen sed.
Ibrahim
4
Erweitern / Nicht erweitern sind Standarddienstprogramme .
Kojiro
4
So cool, dass diese Standard sind. Ich liebe die UNIX-Philosophie . Wäre schön, wenn es an Ort und Stelle tun könnte.
Matthew Flaschen
3
Ich denke nicht, dass Unerweiterung hier funktionieren wird. Es konvertiert nur die führenden Leerzeichen und nur mit zwei oder mehr Leerzeichen. Siehe hier: lists.gnu.org/archive/html/bug-textutils/2001-01/msg00025.html
Olala
13
Nur zur Vorsicht - Unerweiterung konvertiert kein einzelnes Leerzeichen in eine Registerkarte. Wenn Sie alle Läufe von 0x20 Zeichen blind in eine einzige Registerkarte konvertieren müssen, benötigen Sie ein anderes Werkzeug.
Steve S.
44

Ich denke du kannst es mit awk versuchen

awk -v OFS="\t" '$1=$1' file1

oder SED, wenn Sie bevorzugen

sed 's/[:blank:]+/,/g' thefile.txt > the_modified_copy.txt

oder sogar tr

tr -s '\t' < thefile.txt | tr '\t' ' ' > the_modified_copy.txt

oder eine vereinfachte Version der von Sam Bisbee vorgeschlagenen tr-Lösung

tr ' ' \\t < someFile > someFile
Jonathan
quelle
4
In Ihrem sed-Beispiel schreiben Best Practices vor, dass Sie tr verwenden, um einzelne Zeichen aus Gründen der Effizienz / Geschwindigkeit durch sed zu ersetzen. Auch tr Beispiel ist viel einfacher auf diese Weise:tr ' ' \\t < someFile > someFile
Sam Bisbee
2
Natürlich hat tr eine bessere Leistung als sed, aber der Hauptgrund, warum ich Unix liebe, ist, dass es viele Möglichkeiten gibt, etwas zu tun. Wenn Sie diese Ersetzung mehrmals durchführen möchten, suchen Sie nach einer Lösung mit einer guten Leistung. Wenn Sie dies jedoch nur einmal tun, suchen Sie nach einer Lösung, die einen Befehl enthält, mit dem Sie sich wohl fühlen.
Jonathan
2
arg. Ich musste Versuch und Irrtum anwenden, damit das Sed funktioniert. Ich habe keine Ahnung, warum ich dem Pluszeichen so entkommen musste:ls -l | sed "s/ \+/ /g"
Jess
Mit awk -v OFS="\t" '$1=$1' file1bemerkte ich , dass , wenn Sie eine Zeile , die mit der Nummer 0 (zB haben 0 1 2), dann wird die Zeile aus dem Ergebnis weggelassen werden.
Nikola Novak
@Jess Sie haben den regulären Ausdruck "korrekte Standardsyntax" gefunden. Standardmäßig behandelt sed ein einzelnes (nicht entflohenes) Pluszeichen als einfaches Zeichen. Gleiches gilt für einige andere Zeichen wie '?', ... Weitere Informationen finden Sie hier: gnu.org/software/sed/manual/html_node/… . Ähnliche Syntaxdetails finden Sie hier (beachten Sie, dass dies man for grep ist, nicht sed): gnu.org/software/grep/manual/grep.html#Basic-vs-Extended .
Victor Yarema
11

Verwenden von Perl :

perl -p -i -e 's/ /\t/g' file.txt
John Millikin
quelle
3
Hatte ein ähnliches Problem beim Ersetzen aufeinanderfolgender Leerzeichen durch eine einzelne Registerkarte. Perl arbeitete nur mit dem Hinzufügen eines '+' zum regulären Ausdruck.
Todd
Natürlich wollte ich das Gegenteil tun: Tabulatoren in zwei Leerzeichen konvertieren:perl -p -i -e 's/\t/ /g' *.java
TimP
Kann ich das rekursiv machen?
Aaron Franke
9

besser tr Befehl ein :

tr [:blank:] \\t

Dadurch wird die Ausgabe von beispielsweise entpacken -l für die weitere Verarbeitung mit grep, cut usw. bereinigt .

z.B,

unzip -l some-jars-and-textfiles.zip | tr [:blank:] \\t | cut -f 5 | grep jar
Tarkin
quelle
Ich muss keine Anführungszeichen verwenden, um es zum Laufen zu bringen:tr [:blank:] \\t
Ömer An
3

Laden Sie das folgende Skript herunter und führen Sie es aus, um Soft-Tabs in Nur-Text-Dateien rekursiv in Hard-Tabs zu konvertieren.

Platzieren Sie das Skript in dem Ordner, der die Nur-Text-Dateien enthält, und führen Sie es aus.

#!/bin/bash

find . -type f -and -not -path './.git/*' -exec grep -Iq . {} \; -and -print | while read -r file; do {
    echo "Converting... "$file"";
    data=$(unexpand --first-only -t 4 "$file");
    rm "$file";
    echo "$data" > "$file";
}; done;
Daka
quelle
2

Beispielbefehl zum Konvertieren jeder .js-Datei unter dem aktuellen Verzeichnis in Tabulatoren (nur führende Leerzeichen werden konvertiert):

find . -name "*.js" -exec bash -c 'unexpand -t 4 --first-only "$0" > /tmp/totabbuff && mv /tmp/totabbuff "$0"' {} \;
Arkod
quelle
Getestet in Cygwin unter Windows 7.
Arkod
1

Sie können auch verwenden astyle. Ich fand es sehr nützlich und es hat auch mehrere Möglichkeiten:

Tab and Bracket Options:
   If  no  indentation  option is set, the default option of 4 spaces will be used. Equivalent to -s4 --indent=spaces=4.  If no brackets option is set, the
   brackets will not be changed.

   --indent=spaces, --indent=spaces=#, -s, -s#
          Indent using # spaces per indent. Between 1 to 20.  Not specifying # will result in a default of 4 spaces per indent.

   --indent=tab, --indent=tab=#, -t, -t#
          Indent using tab characters, assuming that each tab is # spaces long.  Between 1 and 20. Not specifying # will result in a default assumption  of
          4 spaces per tab.`
Ankur Agarwal
quelle
0

Wenn Sie alle aufeinander folgenden Leerzeichen in einer Zeile durch eine Registerkarte ersetzen möchten tr -s '[:blank:]' '\t'.

[root@sysresccd /run/archiso/img_dev]# sfdisk -l -q -o Device,Start /dev/sda
Device         Start
/dev/sda1       2048
/dev/sda2     411648
/dev/sda3    2508800
/dev/sda4   10639360
/dev/sda5   75307008
/dev/sda6   96278528
/dev/sda7  115809778
[root@sysresccd /run/archiso/img_dev]# sfdisk -l -q -o Device,Start /dev/sda | tr -s '[:blank:]' '\t'
Device  Start
/dev/sda1       2048
/dev/sda2       411648
/dev/sda3       2508800
/dev/sda4       10639360
/dev/sda5       75307008
/dev/sda6       96278528
/dev/sda7       115809778

Wenn Sie über das Ersetzen aller Leerzeichen (z. B. Leerzeichen, Tabulatoren, Zeilenumbrüche usw.) sprechen, dann tr -s '[:space:]'.

[root@sysresccd /run/archiso/img_dev]# sfdisk -l -q -o Device,Start /dev/sda | tr -s '[:space:]' '\t'
Device  Start   /dev/sda1       2048    /dev/sda2       411648  /dev/sda3       2508800 /dev/sda4       10639360        /dev/sda5       75307008        /dev/sda6     96278528        /dev/sda7       115809778  

Wenn Sie über das Reparieren einer durch Tabulatoren beschädigten Datei sprechen, verwenden Sie expandund unexpandwie in anderen Antworten erwähnt.

Spitzmaus
quelle
0

Mit sed :

T=$(printf "\t")
sed "s/[[:blank:]]\+/$T/g"

oder

sed "s/[[:space:]]\+/$T/g"
Tibor
quelle
-1

Dadurch werden aufeinanderfolgende Leerzeichen durch ein Leerzeichen (jedoch keine Registerkarte) ersetzt.

tr -s '[:blank:]'

Dadurch werden aufeinanderfolgende Leerzeichen durch eine Registerkarte ersetzt.

tr -s '[:blank:]' '\t'
mel
quelle
Tatsächlich -cersetzt es durch das fortlaufende Zeichen, die keine Leerzeichen sind.
Wingedsubmariner
1
Die Frage betrifft Tabs, dies ist keine Antwort.
Matthew Read