GNU/Linux >> LINUX-Kenntnisse >  >> Linux

4 Grundlegende und praktische Verwendung des Cut-Befehls unter Linux

Der Cut-Befehl ist das kanonische Werkzeug, um „Spalten“ aus einer Textdatei zu entfernen. In diesem Zusammenhang kann eine „Spalte“ als eine Reihe von Zeichen oder Bytes definiert werden, die durch ihre physische Position auf der Zeile identifiziert werden, oder als eine Reihe von Feldern, die durch ein Trennzeichen begrenzt sind.

Ich habe bereits früher über die Verwendung von AWK-Befehlen geschrieben. In dieser ausführlichen Anleitung erkläre ich vier wesentliche und praktische Beispiele für den Befehl cut in Linux, die Ihnen sehr helfen werden.

4 Praktische Beispiele für den Cut-Befehl unter Linux

Wenn Sie es vorziehen, können Sie sich dieses Video ansehen, in dem die gleichen praktischen Beispiele für Schnittbefehle erklärt werden, die ich im Artikel aufgelistet habe.

1. Arbeiten mit Zeichenbereichen

Bei Aufruf mit -c Befehlszeilenoption entfernt der Cut-Befehl Zeichen Bereiche.

Wie jeder andere Filter ändert auch der Cut-Befehl die vorhandene Eingabedatei nicht, sondern kopiert die geänderten Daten in die Standardausgabe. Es liegt in Ihrer Verantwortung, die Befehlsausgabe in eine Datei umzuleiten, um das Ergebnis zu speichern, oder eine Pipe zu verwenden, um es als Eingabe an einen anderen Befehl zu senden.

Wenn Sie die im obigen Video verwendeten Beispiel-Testdateien heruntergeladen haben, können Sie die BALANCE.txt sehen Datendatei, die direkt aus einer Buchhaltungssoftware stammt, die meine Frau bei ihrer Arbeit verwendet:

sh$ head BALANCE.txt
ACCDOC    ACCDOCDATE    ACCOUNTNUM ACCOUNTLIB              ACCDOCLIB                        DEBIT          CREDIT
4         1012017       623477     TIDE SCHEDULE           ALNEENRE-4701-LOC                00000001615,00
4         1012017       445452     VAT BS/ENC              ALNEENRE-4701-LOC                00000000323,00
4         1012017       4356       PAYABLES                ALNEENRE-4701-LOC                               00000001938,00
5         1012017       623372     ACCOMODATION GUIDE      ALNEENRE-4771-LOC                00000001333,00
5         1012017       445452     VAT BS/ENC              ALNEENRE-4771-LOC                00000000266,60
5         1012017       4356       PAYABLES                ALNEENRE-4771-LOC                               00000001599,60
6         1012017       4356       PAYABLES                FACT FA00006253 - BIT QUIROBEN                  00000001837,20
6         1012017       445452     VAT BS/ENC              FACT FA00006253 - BIT QUIROBEN   00000000306,20
6         1012017       623795     TOURIST GUIDE BOOK      FACT FA00006253 - BIT QUIROBEN   00000001531,00

Dies ist eine Textdatei mit fester Breite, da die Datenfelder mit einer variablen Anzahl von Leerzeichen aufgefüllt werden, um sicherzustellen, dass sie als gut ausgerichtete Tabelle angezeigt werden.

Als Folge davon beginnt und endet eine Datenspalte immer an derselben Zeichenposition in jeder Zeile. Es gibt jedoch einen kleinen Fallstrick:Trotz seines Namens ist der cut Der Befehl erfordert tatsächlich, dass Sie den Datenbereich angeben, den Sie behalten möchten , nicht der Bereich, den Sie entfernen möchten . Also, wenn ich nur brauche die ACCOUNTNUM und ACCOUNTLIB Spalten in der obigen Datendatei würde ich Folgendes schreiben:

sh$ cut -c 25-59 BALANCE.txt | head
ACCOUNTNUM ACCOUNTLIB
623477     TIDE SCHEDULE
445452     VAT BS/ENC
4356       /accountPAYABLES
623372     ACCOMODATION GUIDE
445452     VAT BS/ENC
4356       PAYABLES
4356       PAYABLES
445452     VAT BS/ENC
623795     TOURIST GUIDE BOOK

Was ist ein Bereich?

Wie wir gerade gesehen haben, erfordert der cut-Befehl die Angabe des Bereichs von Daten, die wir behalten möchten. Lassen Sie uns also formeller einführen, was ein Bereich ist:für den cut Befehl wird ein Bereich durch eine Anfangs- und eine Endposition definiert, die durch einen Bindestrich getrennt sind. Bereiche sind 1-basiert, d. h. das erste Element der Zeile ist die Elementnummer 1, nicht 0. Bereiche sind inklusive:Der Anfang und das Ende werden in der Ausgabe beibehalten, ebenso wie alle Zeichen dazwischen. Es ist ein Fehler, einen Bereich anzugeben, dessen Endposition vor („niedriger“) als seine Startposition liegt. Als Abkürzung können Sie den Anfang oder weglassen Endwert wie in der folgenden Tabelle beschrieben:

  • a-b :der Bereich zwischen a und b (einschließlich)
  • a :entspricht dem Bereich a-a
  • -b :Äquivalent zu 1-a
  • b- :Äquivalent zu b-∞

Mit den Ausschneidebefehlen können Sie mehrere Bereiche angeben, indem Sie sie durch ein Komma trennen. Hier sind ein paar Beispiele:

# Keep characters from 1 to 24 (inclusive)
cut -c -24 BALANCE.txt

# Keep characters from 1 to 24 and 36 to 59 (inclusive)
cut -c -24,36-59 BALANCE.txt

# Keep characters from 1 to 24, 36 to 59 and 93 to the end of the line (inclusive)
cut -c -24,36-59,93- BALANCE.txt

Eine Einschränkung (oder Funktion, je nach Sichtweise) des cut Befehl ist, dass es die Daten niemals neu anordnet . Der folgende Befehl liefert also genau das gleiche Ergebnis wie der vorherige, obwohl die Bereiche in einer anderen Reihenfolge angegeben werden:

cut -c 93-,-24,36-59 BALANCE.txt

Das kannst du ganz einfach mit diff überprüfen Befehl:

diff -s <(cut -c -24,36-59,93- BALANCE.txt) \
              <(cut -c 93-,-24,36-59 BALANCE.txt)
Files /dev/fd/63 and /dev/fd/62 are identical

Ebenso der cut Befehl dupliziert niemals Daten :

# One might expect that could be a way to repeat
# the first column three times, but no...
cut -c -10,-10,-10 BALANCE.txt | head -5
ACCDOC
4
4
4
5

Erwähnenswert war ein Vorschlag für ein -o Option, um diese beiden letzten Einschränkungen aufzuheben und den cut zu ermöglichen Dienstprogramm zum Neuordnen oder Duplizieren von Daten. Dies wurde jedoch vom POSIX-Komiteeabgelehnt, „weil diese Art der Verbesserung außerhalb des Geltungsbereichs des IEEE P1003.2b-Standardentwurfs liegt.“

Ich persönlich kenne keine gekürzte Version, die diesen Vorschlag als Erweiterung implementiert. Aber wenn ja, teilen Sie uns das bitte über den Kommentarbereich mit!

2. Arbeiten mit Byte-Bereichen

Bei Aufruf mit -b Befehlszeilenoption entfernt der cut-Befehl Byte Bereiche.

Auf den ersten Blick gibt es keinen offensichtlichen Unterschied zwischen Charakter und Byte Bereiche:

sh$ diff -s <(cut -b -24,36-59,93- BALANCE.txt) \
              <(cut -c -24,36-59,93- BALANCE.txt)
Files /dev/fd/63 and /dev/fd/62 are identical

Das liegt daran, dass meine Beispieldatendatei die US-ASCII-Zeichenkodierung („charset“) als file -i verwendet Befehl kann es richtig erraten:

sh$ file -i BALANCE.txt
BALANCE.txt: text/plain; charset=us-ascii

Bei dieser Zeichencodierung gibt es eine Eins-zu-Eins-Zuordnung zwischen Zeichen und Bytes. Mit nur einem Byte können Sie theoretisch bis zu 256 verschiedene Zeichen (Ziffern, Buchstaben, Satzzeichen, Symbole, …) allgemein gefunden). Wie auch immer, selbst wenn wir den vollen Byte-Bereich nutzen könnten, wäre das bei weitem nicht genug, um die Vielfalt der menschlichen Schrift zu speichern. So ist heute die Eins-zu-Eins-Zuordnung zwischen Zeichen und Byte eher die Ausnahme als die Norm und wird fast immer durch die allgegenwärtige UTF-8-Multibyte-Kodierung ersetzt. Sehen wir uns nun an, wie der cut-Befehl damit umgehen könnte.

Arbeiten mit Multibyte-Zeichen

Wie ich bereits sagte, stammen die Beispieldatendateien, die als Beispiele für diesen Artikel verwendet wurden, aus einer Buchhaltungssoftware, die von meiner Frau verwendet wird. Es fügt hinzu, dass sie diese Software kürzlich aktualisiert hat und danach waren die exportierten Textdateien geringfügig anders. Ich lasse Sie versuchen, den Unterschied selbst zu erkennen:

sh$ head BALANCE-V2.txt
ACCDOC    ACCDOCDATE    ACCOUNTNUM ACCOUNTLIB              ACCDOCLIB                        DEBIT          CREDIT
4         1012017       623477     TIDE SCHEDULE           ALNÉENRE-4701-LOC                00000001615,00
4         1012017       445452     VAT BS/ENC              ALNÉENRE-4701-LOC                00000000323,00
4         1012017       4356       PAYABLES                ALNÉENRE-4701-LOC                               00000001938,00
5         1012017       623372     ACCOMODATION GUIDE      ALNÉENRE-4771-LOC                00000001333,00
5         1012017       445452     VAT BS/ENC              ALNÉENRE-4771-LOC                00000000266,60
5         1012017       4356       PAYABLES                ALNÉENRE-4771-LOC                               00000001599,60
6         1012017       4356       PAYABLES                FACT FA00006253 - BIT QUIROBEN                  00000001837,20
6         1012017       445452     VAT BS/ENC              FACT FA00006253 - BIT QUIROBEN   00000000306,20
6         1012017       623795     TOURIST GUIDE BOOK      FACT FA00006253 - BIT QUIROBEN   00000001531,00

Der Titel dieses Abschnitts kann Ihnen dabei helfen, herauszufinden, was sich geändert hat. Aber, gefunden oder nicht, sehen wir uns jetzt die Folgen dieser Änderung an:

sh$ cut -c 93-,-24,36-59 BALANCE-V2.txt
ACCDOC    ACCDOCDATE    ACCOUNTLIB              DEBIT          CREDIT
4         1012017       TIDE SCHEDULE            00000001615,00
4         1012017       VAT BS/ENC               00000000323,00
4         1012017       PAYABLES                                00000001938,00
5         1012017       ACCOMODATION GUIDE       00000001333,00
5         1012017       VAT BS/ENC               00000000266,60
5         1012017       PAYABLES                                00000001599,60
6         1012017       PAYABLES                               00000001837,20
6         1012017       VAT BS/ENC              00000000306,20
6         1012017       TOURIST GUIDE BOOK      00000001531,00
19        1012017       SEMINAR FEES            00000000080,00
19        1012017       PAYABLES                               00000000080,00
28        1012017       MAINTENANCE             00000000746,58
28        1012017       VAT BS/ENC              00000000149,32
28        1012017       PAYABLES                               00000000895,90
31        1012017       PAYABLES                                00000000240,00
31        1012017       VAT BS/DEBIT             00000000040,00
31        1012017       ADVERTISEMENTS           00000000200,00
32        1012017       WATER                   00000000202,20
32        1012017       VAT BS/DEBIT            00000000020,22
32        1012017       WATER                   00000000170,24
32        1012017       VAT BS/DEBIT            00000000009,37
32        1012017       PAYABLES                               00000000402,03
34        1012017       RENTAL COSTS            00000000018,00
34        1012017       PAYABLES                               00000000018,00
35        1012017       MISCELLANEOUS CHARGES   00000000015,00
35        1012017       VAT BS/DEBIT            00000000003,00
35        1012017       PAYABLES                               00000000018,00
36        1012017       LANDLINE TELEPHONE        00000000069,14
36        1012017       VAT BS/ENC                00000000013,83

Oben habe ich die Befehlsausgabe in-extenso kopiert Es sollte also offensichtlich sein, dass bei der Spaltenausrichtung etwas schief gelaufen ist.

Die Erklärung ist, dass die ursprüngliche Datendatei nur US-ASCII-Zeichen enthielt (Symbole, Satzzeichen, Zahlen und lateinische Buchstaben ohne diakritische Zeichen)

Aber wenn Sie sich die nach dem Software-Update erstellte Datei genau ansehen, können Sie sehen, dass die neue Exportdatendatei jetzt Buchstaben mit Akzenten beibehält. Beispielsweise wird das Unternehmen mit dem Namen „ALNÉENRE“ jetzt korrekt geschrieben, während es zuvor als „ALNEENRE“ (ohne Akzent) exportiert wurde

Die file -i Das Dienstprogramm hat diese Änderung nicht übersehen, da es die Datei jetzt als UTF-8-codiert meldet:

sh$ file -i BALANCE-V2.txt
BALANCE-V2.txt: text/plain; charset=utf-8

Um zu sehen, wie akzentuierte Buchstaben in einer UTF-8-Datei kodiert werden, können wir den hexdump verwenden Dienstprogramm, mit dem wir direkt auf die Bytes in einer Datei schauen können:

# To reduce clutter, let's focus only on the second line of the file
sh$ sed '2!d' BALANCE-V2.txt
4         1012017       623477     TIDE SCHEDULE           ALNÉENRE-4701-LOC                00000001615,00
sh$ sed '2!d' BALANCE-V2.txt  | hexdump -C
00000000  34 20 20 20 20 20 20 20  20 20 31 30 31 32 30 31  |4         101201|
00000010  37 20 20 20 20 20 20 20  36 32 33 34 37 37 20 20  |7       623477  |
00000020  20 20 20 54 49 44 45 20  53 43 48 45 44 55 4c 45  |   TIDE SCHEDULE|
00000030  20 20 20 20 20 20 20 20  20 20 20 41 4c 4e c3 89  |           ALN..|
00000040  45 4e 52 45 2d 34 37 30  31 2d 4c 4f 43 20 20 20  |ENRE-4701-LOC   |
00000050  20 20 20 20 20 20 20 20  20 20 20 20 20 30 30 30  |             000|
00000060  30 30 30 30 31 36 31 35  2c 30 30 20 20 20 20 20  |00001615,00     |
00000070  20 20 20 20 20 20 20 20  20 20 20 0a              |           .|
0000007c

Auf der Zeile 00000030 des hexdump ausgegeben, nach einer Reihe von Leerzeichen (Byte 20 ), können Sie sehen:

  • der Buchstabe A wird als Byte 41 kodiert ,
  • der Buchstabe L wird durch das Byte 4c kodiert ,
  • und dem Buchstaben N wird als Byte 4e kodiert .

Aber der lateinische Großbuchstabe E mit Akut (da es der offizielle Name des Buchstabens É ist im Unicode-Standard) wird mit den zwei codiert Bytes c3 89

Und hier ist das Problem:die Verwendung des cut Der Befehl mit Bereichen, die als Byte-Positionen ausgedrückt werden, funktioniert gut für Codierungen mit fester Länge, aber nicht für Codierungen mit variabler Länge wie UTF-8 oder Shift JIS. Dies wird im folgenden nicht normativen Auszug des POSIX-Standards deutlich erklärt:

Frühere Versionen des Cut-Dienstprogramms funktionierten in einer Umgebung, in der Bytes und Zeichen als gleichwertig betrachtet wurden (Modulo und -Verarbeitung in einigen Implementierungen). In der erweiterten Welt der Multibyte-Zeichen wurde die neue Option -b hinzugefügt.

He, Moment mal! Ich habe das -b nicht verwendet Option im „fehlerhaften“ Beispiel oben, aber die -c Möglichkeit. Also, sollte nicht die funktioniert haben?!?

Ja, das sollte :Es ist bedauerlich, aber wir sind im Jahr 2018 und trotzdem verarbeitet die GNU-Implementierung des Cut-Dienstprogramms ab GNU Coreutils 8.30 Multibyte-Zeichen immer noch nicht richtig. Um die GNU-Dokumentation zu zitieren, der -c Die Option ist „Vorerst dasselbe wie -b, aber die Internationalisierung wird das ändern[… ]“ — eine Erwähnung, die seit mehr als 10 Jahren besteht!

Andererseits ist die OpenBSD-Implementierung des Cut-Dienstprogramms POSIX-kompatibel und wird die aktuellen Locale-Einstellungen berücksichtigen, um Multi-Byte-Zeichen richtig zu handhaben:

# Ensure subseauent commands will know we are using UTF-8 encoded
# text files
openbsd-6.3$ export LC_CTYPE=en_US.UTF-8

# With the `-c` option, cut works properly with multi-byte characters
openbsd-6.3$ cut -c -24,36-59,93- BALANCE-V2.txt
ACCDOC    ACCDOCDATE    ACCOUNTLIB              DEBIT          CREDIT
4         1012017       TIDE SCHEDULE           00000001615,00
4         1012017       VAT BS/ENC              00000000323,00
4         1012017       PAYABLES                               00000001938,00
5         1012017       ACCOMODATION GUIDE      00000001333,00
5         1012017       VAT BS/ENC              00000000266,60
5         1012017       PAYABLES                               00000001599,60
6         1012017       PAYABLES                               00000001837,20
6         1012017       VAT BS/ENC              00000000306,20
6         1012017       TOURIST GUIDE BOOK      00000001531,00
19        1012017       SEMINAR FEES            00000000080,00
19        1012017       PAYABLES                               00000000080,00
28        1012017       MAINTENANCE             00000000746,58
28        1012017       VAT BS/ENC              00000000149,32
28        1012017       PAYABLES                               00000000895,90
31        1012017       PAYABLES                               00000000240,00
31        1012017       VAT BS/DEBIT            00000000040,00
31        1012017       ADVERTISEMENTS          00000000200,00
32        1012017       WATER                   00000000202,20
32        1012017       VAT BS/DEBIT            00000000020,22
32        1012017       WATER                   00000000170,24
32        1012017       VAT BS/DEBIT            00000000009,37
32        1012017       PAYABLES                               00000000402,03
34        1012017       RENTAL COSTS            00000000018,00
34        1012017       PAYABLES                               00000000018,00
35        1012017       MISCELLANEOUS CHARGES   00000000015,00
35        1012017       VAT BS/DEBIT            00000000003,00
35        1012017       PAYABLES                               00000000018,00
36        1012017       LANDLINE TELEPHONE      00000000069,14
36        1012017       VAT BS/ENC              00000000013,83

Wie erwartet bei Verwendung von -b Byte-Modus anstelle des -c Zeichenmodus verhält sich die Cut-Implementierung von OpenBSD wie der alte cut :

openbsd-6.3$ cut -b -24,36-59,93- BALANCE-V2.txt
ACCDOC    ACCDOCDATE    ACCOUNTLIB              DEBIT          CREDIT
4         1012017       TIDE SCHEDULE            00000001615,00
4         1012017       VAT BS/ENC               00000000323,00
4         1012017       PAYABLES                                00000001938,00
5         1012017       ACCOMODATION GUIDE       00000001333,00
5         1012017       VAT BS/ENC               00000000266,60
5         1012017       PAYABLES                                00000001599,60
6         1012017       PAYABLES                               00000001837,20
6         1012017       VAT BS/ENC              00000000306,20
6         1012017       TOURIST GUIDE BOOK      00000001531,00
19        1012017       SEMINAR FEES            00000000080,00
19        1012017       PAYABLES                               00000000080,00
28        1012017       MAINTENANCE             00000000746,58
28        1012017       VAT BS/ENC              00000000149,32
28        1012017       PAYABLES                               00000000895,90
31        1012017       PAYABLES                                00000000240,00
31        1012017       VAT BS/DEBIT             00000000040,00
31        1012017       ADVERTISEMENTS           00000000200,00
32        1012017       WATER                   00000000202,20
32        1012017       VAT BS/DEBIT            00000000020,22
32        1012017       WATER                   00000000170,24
32        1012017       VAT BS/DEBIT            00000000009,37
32        1012017       PAYABLES                               00000000402,03
34        1012017       RENTAL COSTS            00000000018,00
34        1012017       PAYABLES                               00000000018,00
35        1012017       MISCELLANEOUS CHARGES   00000000015,00
35        1012017       VAT BS/DEBIT            00000000003,00
35        1012017       PAYABLES                               00000000018,00
36        1012017       LANDLINE TELEPHONE        00000000069,14
36        1012017       VAT BS/ENC                00000000013,83

3. Arbeiten mit Feldern

In gewisser Weise ist das Arbeiten mit Feldern in einer Textdatei mit Trennzeichen für den cut einfacher Dienstprogramm, da es nur die (ein Byte) Feldtrennzeichen in jeder Zeile lokalisieren muss und dann den Feldinhalt wörtlich in die Ausgabe kopiert, ohne sich um Codierungsprobleme zu kümmern.

Hier ist ein Beispiel für eine Textdatei mit Trennzeichen:

sh$ head BALANCE.csv
ACCDOC;ACCDOCDATE;ACCOUNTNUM;ACCOUNTLIB;ACCDOCLIB;DEBIT;CREDIT
4;1012017;623477;TIDE SCHEDULE;ALNEENRE-4701-LOC;00000001615,00;
4;1012017;445452;VAT BS/ENC;ALNEENRE-4701-LOC;00000000323,00;
4;1012017;4356;PAYABLES;ALNEENRE-4701-LOC;;00000001938,00
5;1012017;623372;ACCOMODATION GUIDE;ALNEENRE-4771-LOC;00000001333,00;
5;1012017;445452;VAT BS/ENC;ALNEENRE-4771-LOC;00000000266,60;
5;1012017;4356;PAYABLES;ALNEENRE-4771-LOC;;00000001599,60
6;1012017;4356;PAYABLES;FACT FA00006253 - BIT QUIROBEN;;00000001837,20
6;1012017;445452;VAT BS/ENC;FACT FA00006253 - BIT QUIROBEN;00000000306,20;
6;1012017;623795;TOURIST GUIDE BOOK;FACT FA00006253 - BIT QUIROBEN;00000001531,00;

Sie kennen dieses Dateiformat vielleicht als CSV (für Comma-separated Value), auch wenn das Feldtrennzeichen nicht immer ein Komma ist. Beispielsweise das Semikolon (; ) wird häufig als Feldtrennzeichen verwendet und ist oft die Standardauswahl beim Exportieren von Daten als „CSV“ in Länder, die bereits das Komma als Dezimaltrennzeichen verwenden (wie wir es in Frankreich tun – daher die Wahl dieses Zeichens in meiner Beispieldatei ). Eine andere beliebte Variante verwendet ein Tabulatorzeichen als Feldtrennzeichen, wodurch eine Datei mit tabulatorgetrennten Werten entsteht. Schließlich ist in der Unix- und Linux-Welt der Doppelpunkt (: ) ist ein weiteres relativ gebräuchliches Feldtrennzeichen, das Sie beispielsweise im Standard /etc/passwd finden können und /etc/group Dateien.

Wenn Sie ein Textdateiformat mit Trennzeichen verwenden, geben Sie dem Ausschneidebefehl den Feldbereich an, der beibehalten werden soll, indem Sie -f verwenden Option, und Sie müssen das Trennzeichen mit -d angeben Option (ohne das -d Option verwendet das Cut-Dienstprogramm standardmäßig ein Tabulatorzeichen als Trennzeichen):

sh$ cut -f 5- -d';' BALANCE.csv | head
ACCDOCLIB;DEBIT;CREDIT
ALNEENRE-4701-LOC;00000001615,00;
ALNEENRE-4701-LOC;00000000323,00;
ALNEENRE-4701-LOC;;00000001938,00
ALNEENRE-4771-LOC;00000001333,00;
ALNEENRE-4771-LOC;00000000266,60;
ALNEENRE-4771-LOC;;00000001599,60
FACT FA00006253 - BIT QUIROBEN;;00000001837,20
FACT FA00006253 - BIT QUIROBEN;00000000306,20;
FACT FA00006253 - BIT QUIROBEN;00000001531,00;

Handhabungszeilen, die das Trennzeichen nicht enthalten

Was aber, wenn eine Zeile in der Eingabedatei das Trennzeichen nicht enthält? Es ist verlockend, sich das als eine Zeile vorzustellen, die nur das erste Feld enthält. Aber das ist nicht was das Schnittdienstprogramm macht.

Standardmäßig bei Verwendung von -f Option ausschneiden, gibt das Cut-Dienstprogramm immer wörtlich eine Zeile aus, die das Trennzeichen nicht enthält (wahrscheinlich unter der Annahme, dass dies eine Zeile ohne Daten ist, wie eine Kopfzeile oder eine Art Kommentar):

sh$ (echo "# 2018-03 BALANCE"; cat BALANCE.csv) > BALANCE-WITH-HEADER.csv

sh$ cut -f 6,7 -d';' BALANCE-WITH-HEADER.csv | head -5
# 2018-03 BALANCE
DEBIT;CREDIT
00000001615,00;
00000000323,00;
;00000001938,00

Mit dem -s können Sie dieses Verhalten umkehren, also cut wird diese Zeile immer ignorieren:

sh$ cut -s -f 6,7 -d';' BALANCE-WITH-HEADER.csv | head -5
DEBIT;CREDIT
00000001615,00;
00000000323,00;
;00000001938,00
00000001333,00;

Wenn Sie in einer Hacking-Stimmung sind, können Sie diese Funktion als relativ obskuren Weg ausnutzen, um nur Zeilen zu behalten, die ein bestimmtes Zeichen enthalten:

# Keep lines containing a `e`
sh$ printf "%s\n" {mighty,bold,great}-{condor,monkey,bear} | cut -s -f 1- -d'e'

Ausgabetrennzeichen ändern

Als Erweiterung erlaubt die GNU-Implementierung von cut mit dem --output-delimiter ein anderes Feldtrennzeichen für die Ausgabe zu verwenden Möglichkeit:

sh$ cut -f 5,6- -d';' --output-delimiter="*" BALANCE.csv | head
ACCDOCLIB*DEBIT*CREDIT
ALNEENRE-4701-LOC*00000001615,00*
ALNEENRE-4701-LOC*00000000323,00*
ALNEENRE-4701-LOC**00000001938,00
ALNEENRE-4771-LOC*00000001333,00*
ALNEENRE-4771-LOC*00000000266,60*
ALNEENRE-4771-LOC**00000001599,60
FACT FA00006253 - BIT QUIROBEN**00000001837,20
FACT FA00006253 - BIT QUIROBEN*00000000306,20*
FACT FA00006253 - BIT QUIROBEN*00000001531,00*

Beachten Sie, dass in diesem Fall alle Vorkommen des Feldtrennzeichens ersetzt werden und nicht nur die an der Grenze der Bereiche, die in den Befehlszeilenargumenten angegeben sind.

4. Nicht-POSIX-GNU-Erweiterungen

Apropos Nicht-POSIX-GNU-Erweiterung, ein paar davon können besonders nützlich sein. Erwähnenswert sind die folgenden Erweiterungen, die genauso gut mit Byte-, Zeichen- (was das in der aktuellen GNU-Implementierung bedeutet) oder Feldbereichen funktionieren:--complement

Stellen Sie sich diese Option wie das Ausrufezeichen in einer Sed-Adresse vor (! ); Anstatt die Daten im angegebenen Bereich zu halten, cut behält Daten, die NICHT mit dem Bereich übereinstimmen

# Keep only field 5
sh$ cut -f 5 -d';' BALANCE.csv |head -3
ACCDOCLIB
ALNEENRE-4701-LOC
ALNEENRE-4701-LOC

# Keep all but field 5
sh$ cut --complement -f 5 -d';' BALANCE.csv |head -3
ACCDOC;ACCDOCDATE;ACCOUNTNUM;ACCOUNTLIB;DEBIT;CREDIT
4;1012017;623477;TIDE SCHEDULE;00000001615,00;
4;1012017;445452;VAT BS/ENC;00000000323,00;

--zero-terminated (-z )

Verwenden Sie anstelle des Zeilenumbruchzeichens das NUL-Zeichen als Zeilenabschlusszeichen. Das -z Die Option ist besonders nützlich, wenn Ihre Daten möglicherweise eingebettete Zeilenumbruchzeichen enthalten, z. B. beim Arbeiten mit Dateinamen (da Zeilenumbruch ein gültiges Zeichen in einem Dateinamen ist, NUL jedoch nicht).

Um Ihnen zu zeigen, wie das -z Option funktioniert, machen wir ein kleines Experiment. Zuerst erstellen wir eine Datei, deren Name eingebettete neue Zeilen enthält:

bash$ touch

Nehmen wir nun an, ich möchte die ersten 5 Zeichen jeder *.txt anzeigen Dateinamen. Eine naive Lösung wird hier kläglich scheitern:

sh$ ls -1 *.txt | cut -c 1-5
BALAN
BALAN
EMPTY
FILE
WITH
NAME.

Vielleicht haben Sie ls bereits gelesen wurde für den menschlichen Gebrauch entwickelt, und die Verwendung in einer Befehlspipeline ist ein Anti-Pattern (das ist es in der Tat). Verwenden wir also den find Befehl stattdessen:

sh$ find . -name '*.txt' -printf "%f\n" | cut -c 1-5
BALAN
EMPTY
FILE
WITH
NAME.
BALAN

und … das im Grunde das gleiche fehlerhafte Ergebnis wie zuvor erzeugte (allerdings in einer anderen Reihenfolge, weil ls sortiert implizit die Dateinamen, etwas das find Befehl geht nicht).

Das Problem ist in beiden Fällen der cut Der Befehl kann nicht zwischen einem Zeilenumbruchzeichen als Teil eines Datenfelds (dem Dateinamen) und einem Zeilenumbruchzeichen unterscheiden, das als Datensatzende-Markierung verwendet wird. Aber mit dem NUL-Byte (\0 ), da der Zeilenabschluss die Verwirrung beseitigt, damit wir endlich das erwartete Ergebnis erhalten:

# I was told (?) some old versions of tr require using \000 instead of \0
# to denote the NUL character (let me know if you needed that change!)
sh$ find . -name '*.txt' -printf "%f\0" | cut -z -c 1-5| tr '\0' '\n'
BALAN
EMPTY
BALAN

Mit diesem letzten Beispiel entfernen wir uns vom Kern dieses Artikels, der der cut war Befehl. Ich lasse Sie also versuchen, selbst herauszufinden, was der abgefahrene "%f\0" bedeutet nach dem -printf Argument von find Befehl oder warum ich den tr verwendet habe Befehl am Ende der Pipeline.

Mit dem Cut-Befehl kann noch viel mehr gemacht werden

Ich habe gerade die gebräuchlichste und meiner Meinung nach wichtigste Verwendung des Cut-Befehls gezeigt. Sie können den Befehl noch praktischer anwenden. Es hängt von Ihrem logischen Denken und Ihrer Vorstellungskraft ab.

Zögern Sie nicht, den Kommentarbereich unten zu verwenden, um Ihre Ergebnisse zu veröffentlichen. Und wenn Ihnen dieser Artikel gefällt, vergessen Sie wie immer nicht, ihn auf Ihren bevorzugten Websites und in sozialen Medien zu teilen!


Linux
  1. Linux-Cat-Befehl:Verwendung und Beispiele

  2. Linux-Befehle:jobs, bg und fg

  3. Der Linux-AWK-Befehl – ​​Syntaxbeispiele für Linux und Unix

  4. Linux-df-Befehl

  5. cut-Befehlsbeispiele in Linux

50 einfacher und nützlicher Linux-Cut-Befehl in Unix mit Beispielen

40 Praktischer und nützlicher awk-Befehl in Linux und BSD

50 Produktiver und praktischer grep-Befehl für Linux-Enthusiasten

16 Praktische und nützliche Beispiele für Echo Command unter Linux

7 Grundlegende und praktische Verwendung des Einfügebefehls in Linux

Cat-Befehl in Linux:Wesentliche und erweiterte Beispiele