So kürzen Sie die zweite Spalte auf die angegebene Länge

9

Gegebene Eingabe des Formulars

XY981743    foobarlkasdf saflkas asfZR!sgfad asdSAD asdsadf SAdfasdf46lk lksad bar foolkasjfdrte

Wie kann ich nur die zweite Spalte abschneiden? Das Trennzeichen ist TAB und die zweite Spalte darf höchstens 75 Zeichen lang sein.

LoukiosValentine79
quelle
Ein bisschen allgemeiner:awk 'BEGIN{OFS=FS="\t"} {$2=substr($2,1,75)}1' file
Fedorqui
Möchten Sie Zeichen nach dem 75. abschneiden (löschen) oder falten (in einer anderen Zeile drucken)? Sollten die Leerzeichen auch auf die 75 Zeichen angerechnet werden oder nicht?
Terdon

Antworten:

7

Wenn Sie nur die ersten 75 Zeichen der zweiten Spalte drucken möchten (einschließlich Leerzeichen und nur zwei Spalten in der Datei), haben Sie folgende Möglichkeiten:

$ perl -pe 's/(\t.{75}).*/$1/' file
XY981743    foobarlkasdf saflkas asfZR!sgfad asdSAD asdsadf SAdfasdf46lk lksad bar fool

Oder mit GNU sed:

$ sed 's/\(.*\t.\{75\}\).*/\1/' file
XY981743    foobarlkasdf saflkas asfZR!sgfad asdSAD asdsadf SAdfasdf46lk lksad bar fool

Oder:

$ sed -r 's/(.*\t.{75}).*/\1/' file
XY981743    foobarlkasdf saflkas asfZR!sgfad asdSAD asdsadf SAdfasdf46lk lksad bar fool

Alternativ können Sie festlegen fold, dass die ersten 91 Zeichen (das sind 8 für die Kennung und weitere 8 für die Registerkarte) ausgeschnitten und nur die erste Zeile gedruckt werden sollen:

$ fold -w 91 file | head -n1
XY981743    foobarlkasdf saflkas asfZR!sgfad asdSAD asdsadf SAdfasdf46lk lksad bar fool

Wenn Ihre Datei mehr als 2 Spalten haben kann und Sie nur die zweite abschneiden möchten, können Sie dies tun (was, wie ich gerade bemerkt habe, nur eine Umformulierung von Stephens Antwort ist ):

$ awk -F"\t" -vOFS="\t" '{$2=substr($2,1,75)}1;' file
XY981743    foobarlkasdf saflkas asfZR!sgfad asdSAD asdsadf SAdfasdf46lk lksad bar fool

Oder (beachten Sie, dass dies unterbrochen wird, wenn die ersten 75 Zeichen der 2. Spalte als regulärer Ausdruck interpretiert werden können):

$ perl -F"\t" -pale 's/$F[1]/substr($F[1],0,75)/e' file
XY981743    foobarlkasdf saflkas asfZR!sgfad asdSAD asdsadf SAdfasdf46lk lksad bar fool
terdon
quelle
Diese können eine andere Spalte als die zweite abschneiden. Ihr erster sedBefehl verwendet auch einen GNUism ( \t).
Stéphane Chazelas
@ StéphaneChazelas was ? \tist ein GNUismus? Ernsthaft? Was ist dann die tragbare Art, eine Registerkarte zu beschreiben?
Terdon
1
Fügen Sie es wörtlich ein, um meine Antwort zu sehen. Die einzige Escape-Sequenz, die auf der LHS portabel erkannt wird, ist \n(und auch hier nicht [...]mit vielen Implementierungen), keine auf der RHS.
Stéphane Chazelas
@ StéphaneChazelas verdammt, danke. Ich habe auch eine Lösung hinzugefügt, die mehrere Spalten verarbeiten kann.
Terdon
Dein letzter perlmacht wenig Sinn. Denken Sie zum Beispiel an eine Eingabe wieaba\t.*
Stéphane Chazelas
10

Teilen Sie awkdie Datei mit Tabulatoren und geben Sie das erste Feld vollständig und die ersten 75 Zeichen (höchstens) des zweiten aus:

awk -F "\t" 'BEGIN { OFS=FS }; { print $1, substr($2, 1, 75); }'

Wie von fedorqui hervorgehoben , können Sie Dateien mit mehr als zwei Feldern verarbeiten, indem Sie die Felder ersetzen, die Sie abschneiden müssen:

awk -F "\t" 'BEGIN { OFS=FS }; { $2=substr($2, 1, 75); print }'

Sie können das substrauf mehrere Felder anwenden , indem Sie sie bei Bedarf durchlaufen.

Stephen Kitt
quelle
@ Stéphane, in welchen Fällen sind die extra ;notwendig?
Stephen Kitt
Sie werden von POSIX benötigt. Jetzt kenne ich keine Implementierung, in der sie erforderlich sind, aber als ich darum bat, dass die POSIX-Anforderung gelockert wird, wurde sie vom Gawk-Betreuer abgelehnt (wo alle Beispiele im Dokument das haben;).
Stéphane Chazelas
Ah, gut zu wissen, danke! Die Spezifikation und die Dokumentation sind also strenger als alle Implementierungen ...
Stephen Kitt
alle Implementierungen , die ich zumindest kenne (nicht so viele). Der Punkt ist, dass das Trennzeichen weggelassen wird, was zu einer nicht standardmäßigen Syntax führt. Aktuelle und zukünftige Implementierungen können und sind daher berechtigt, daran zu ersticken oder Erweiterungen einzuführen, die davon Gebrauch machen (wie beispielsweise eine Ausnahmebehandlung /pattern/ {action} {exception-handling}). Nun, das wäre äußerst unwahrscheinlich, da ;es ziemlich üblich ist , diese wegzulassen .
Stéphane Chazelas
4

Tragbar / POSIXly mit sed:

tab=$(printf '\t')
sed "s/\($tab[^$tab]\{0,75\}\)[^$tab]*/\1/"

Oder um jede Spalte abzuschneiden:

sed "s/\([^$tab]\{75\}\)[^$tab]*/\1/g"
Stéphane Chazelas
quelle
2

Wenn es nur 2 Spalten gibt:

sed -r 's/^([^\t]*\t)(.{0,75}).*/\1\2/'

{0,75}bedeutet, wählen Sie zwischen 0 und 75 Zeichen.
.* ist der entfernte Abschnitt jenseits von char 75.


Wenn es 2 oder mehr Spalten gibt:

sed -r 's/^([^\t]*\t)([^\t]{0,75})[^\t]*(.*)/\1\2\3/' file

[^\t]* ist der entfernte Abschnitt jenseits von char 75.

Peter.O
quelle
Beachten Sie, dass dies GNU voraussetzt sedund POSIXLY_CORRECTnicht in der Umgebung ist.
Stéphane Chazelas